3年前 (2020-10-26)  Java系列 |   抢沙发  296 
文章评分 0 次,平均分 0.0
[收起] 文章目录

在我们的上一篇文章中,我们讨论了如何在运行时使用各种方式加载类。这里我们将看到如何获取该类的元数据、它的方法和字段。

Class是finaljava.lang扩展对象类的包。这个类的实例表示正在运行的Java应用程序中的类和接口。它用于分析和更改类在运行时的动态行为。

Java反射类java.lang.Class

方法java.lang.Class 类

这个类定义了几个方法,我们可以使用这些方法在运行时获取关于方法、构造函数、修改器和类成员的信息。

forName()

该方法以类或接口的完全限定名称作为参数,并返回与其关联的类的实例。

语法:

static Class< ?> forName(String className)

获取类元数据

要获取类的元数据,首先需要使用Class.forName方法。在本例中,我们使用getName()方法获取类的名称,使用getDeclaredFields()获取类的所有字段。请参见下面的示例。

import java.util.Arrays;

// Employee Class
class Employee{

  // Fields 
  int empId;
  String name;
  
  // Constructor
  Employee(int empId, String name){
    this.empId = empId;
    this.name = name;
  }
  
  // Method
  void showInfo() {
    System.out.println("Employee Id: "+empId);
    System.out.println("Employee Name: "+name);
  }
}

class Demo{
  public static void main(String[] args) throws ClassNotFoundException {
    
    // Employee class
    Class name = Class.forName("myjavaproject.Employee");
    // Get class Name
    System.out.println(name.getName());
    // Get Package
    System.out.println(name.getPackageName());
    System.out.println(name.getTypeName());
    Arrays.stream(name.getDeclaredConstructors()).forEach(System.out::println);
    Arrays.stream(name.getDeclaredFields()).forEach(System.out::println);
    Arrays.stream(name.getDeclaredMethods()).forEach(System.out::println);
  }
} 

输出:

myjavaproject.Employee
myjavaproject
myjavaproject.Employee
myjavaproject.Employee(int,java.lang.String)
int myjavaproject.Employee.empId
java.lang.String myjavaproject.Employee.name
void myjavaproject.Employee.showInfo()

获取字段元数据

为了处理类字段,Java提供了一个字段类,该类位于java.lang.reflect包裹。此类包含有助于获取字段元数据的方法。在这个例子中,您可以看到我们使用类forName加载类,然后加载字段类以获取类的元数据。

import java.lang.reflect.Field;

// Employee Class
class Employee{

  // Fields 
  int empId;
  String name;
  
  // Constructor
  Employee(int empId, String name){
    this.empId = empId;
    this.name = name;
  }
  
  // Method
  void showInfo() {
    System.out.println("Employee Id: "+empId);
    System.out.println("Employee Name: "+name);
  }
}

class Demo{
  public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
    
    // Employee class
    Class name = Class.forName("myjavaproject.Employee");
    // Get Fields metadata
    Field[] field = name.getDeclaredFields();
    for(Field f: field) {
      System.out.print(f.getType()+" ");
      System.out.println(f.getName());
      System.out.println(f.getModifiers());     
    }   
  }
}

输出:

int empId
0
class java.lang.String name
0

获取方法元数据

为了处理类方法,Java提供了一个方法类,该类位于java.lang.reflect包裹。此类包含有助于获取方法元数据的方法。在这个例子中,您可以看到我们使用类forName加载类,然后加载方法类,以获取方法的元数据。

import java.lang.reflect.Method;

// Employee Class
class Employee{

  // Fields 
  int empId;
  String name;
  
  // Constructor
  Employee(int empId, String name){
    this.empId = empId;
    this.name = name;
  }
  
  // Method
  void showInfo() {
    System.out.println("Employee Id: "+empId);
    System.out.println("Employee Name: "+name);
  }
}

class Demo{
  public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
    
    // Employee class
    Class name = Class.forName("myjavaproject.Employee");
    // Get method metadata
    Method[] method = name.getDeclaredMethods();
    for(Method m: method) {
      System.out.println(m);
      System.out.println(m.getDefaultValue());
      System.out.println(m.getModifiers());
      System.out.println(m.getName());
      System.out.println(m.getParameterCount());
      System.out.println(m.getReturnType());
    }   
  }
}
void myjavaproject.Employee.showInfo()
null
0
showInfo
0
void

获取构造函数元数据

一个类可以有几个构造函数,包括参数化的和非参数化的。Java反射提供了由方法组成的构造函数类,可以用来获取构造函数的元数据。在这个例子中,我们使用构造函数类及其方法来获取构造函数的元数据。请参阅下面的示例。

import java.lang.reflect.Constructor;
import java.lang.reflect.Parameter;

// Employee Class
class Employee{

  // Fields 
  int empId;
  String name;
  
  // Constructor
  Employee(int empId, String name){
    this.empId = empId;
    this.name = name;
  }
  
  // Method
  void showInfo() {
    System.out.println("Employee Id: "+empId);
    System.out.println("Employee Name: "+name);
  }
}

class Demo{
  public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
    
    // Employee class
    Class name = Class.forName("myjavaproject.Employee");
    // Get method metadata
    Constructor[] constructor = name.getDeclaredConstructors();
    for(Constructor c: constructor) {
      System.out.println(c);
      System.out.println(c.getModifiers());
      System.out.println(c.getName());
      System.out.println(c.getParameterCount());
      System.out.println(c.getDeclaringClass());
      Parameter[] parameters = c.getParameters();
      for(Parameter p : parameters) {
        System.out.println(p);
      }
      
      Class[] pt = c.getParameterTypes();
      for(Class s : pt) {
        System.out.println(s);
      }
    }   
  }
}

输出:

myjavaproject.Employee(int,java.lang.String)
0
myjavaproject.Employee
2
class myjavaproject.Employee
int arg0
java.lang.String arg1
int
class java.lang.Strings

getConstructors()和getDeclaredConstructors()

方法返回构造函数对象的数组,该数组表示调用对象的所有公共构造函数。记住,这个方法只返回公共构造函数。如果要查看类的所有声明构造函数,请使用getDeclaredConstructors()。下面是两者的一般语法,

Constructor< ?>[] getConstructors();
Constructor< ?>[] getDeclaredConstructors();

示例:getConstructors()和getDeclaredConstructors()方法

这两个方法都用于获取类构造函数,但是getConstructors()只返回公共构造函数,而getDeclaredConstructors()返回所有可用的构造函数。

import java.lang.reflect.*;
class Student
{
  public Student(){}
  public Student(String name){}
}

class Test
{
  public static void main(String args[])
  {
    try
    {
      Class c = Class.forName("Student");
      Constructor< Student>[] ct = c.getConstructors();
      for(int i=0; i< ct.length; i++)
      { System.out.println(ct[i]); }
      Constructor< Student>[]cdt = c.getDeclaredConstructors();
      for(int i=0;i< cdt.length;i++)
      { System.out.println(cdt[i]);}
    }
    catch(Exception e)
    { e.printStackTrace();}
  }
}

输出:

public Student()
public Student(java.lang.String)
public Student()
public Student(java.lang.String)

getMethods()和getDeclaredMethods()

方法返回方法对象的数组,该数组反映调用对象的所有公共方法。getDeclaredMethods()只返回调用类对象的声明方法。两者的语法如下所示,

Method< ?>[] getMethods();
Method< ?>[] getDeclaredMethods();

示例:getDeclaredMethods()方法

让我们举一个例子,在这个例子中,我们使用getDeclaredMethods()方法来获取类中所有声明的方法。请参见下面的示例。

import java.lang.reflect.*;
class Student
{
  public void show(){}
  void display(){}
}

class Test
{
  public static void main(String args[])
  {
    try
    {
      Class c = Class.forName("Student");
      Method md[] = c.getDeclaredMethods();
      for(int i=0; i< md.length; i++ )
      { System.out.println(md[i]); }
    }
    catch(Exception e)
    { e.printStackTrace();}
  }
}

输出:

public void Student.show()
void Student.display()

getFields()和getDeclaredFields()

getFields()返回一个数组,该数组包含字段对象,这些字段对象反映由该类对象表示的类或接口的所有可访问公共成员。getDeclaredFields()返回Field对象的数组,该数组反映由该类对象表示的类或接口声明的所有字段。

Field< ?>[] getFields();
Field< ?>[] getDeclaredFields();

示例:getFields()和getDeclaredFields()方法

要获取类的字段,可以使用getFields()getDeclaredFields()方法。除了getFields只返回公共字段外,这两个都返回字段。请参见下面的示例。

import java.lang.reflect.*;
class Student
{
  public  String name;
  int roll;
}

class Test
{
  public static void main(String args[])
  {
    try
    {
      Class c = Class.forName("Student");
      Field ff[] = c.getFields();
      for(int i=0; i< ff.length; i++)
      { System.out.println(ff[i]); }
      Field f[] = c.getDeclaredFields();
      for(int i=0;i< f.length; i++)
      { System.out.println(f[i]);  }
    }
    catch(Exception e)
    { e.printStackTrace();}
  }
}

输出:

public java.lang.String Student.name
public java.lang.String Student.name
int Student.roll
 

除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/709.html

关于

发表评论

表情 格式

暂无评论

登录

忘记密码 ?

切换登录

注册