Home  >  Article  >  Java  >  How to understand java reflection

How to understand java reflection

藏色散人
藏色散人Original
2019-11-13 10:19:372847browse

How to understand java reflection

How to understand java reflection?

Overview

Java reflection is a mechanism that allows us to obtain internal information of classes such as methods, properties, parent classes, interfaces, etc. at runtime. In other words, reflection is essentially a "reverse" process. When we create an instance of a class through new, it is actually constructed by the Java virtual machine at runtime based on the Class object of this class. Reflection obtains its definition information through the Class object of a class, so that we can access it. Go to its attributes and methods, know the parent class of this class, which interfaces are implemented, and other information.

Class class

We know that using javac can compile a .java file into a .class file. This .class file contains our original definition information for the class (parent classes, interfaces, constructors, properties, methods, etc.). The .class file will be loaded into the Java virtual machine (JVM) by the ClassLoader at runtime. When a .class file is loaded, the JVM will generate a Class object for it. The object we instantiate through new in the program is actually It is constructed based on the corresponding Class object at runtime. To be precise, this Class object is actually an instance of the java.lang.Class8742468051c85b06f0a0af9e3e506b5c generic class. For example, the Class3a588aab6ae1f766128f21e776d37218 object is a Class8742468051c85b06f0a0af9e3e506b5c instance that encapsulates the definition information of the MyClass class. Since the java.lang.Class8742468051c85b06f0a0af9e3e506b5c class does not have a public constructor, we cannot instantiate this class directly. We can obtain a Class object through the following method.

In the following explanation, we will take the People class and the Student class as examples:

public class People {
      private String name;
      private int age;
      public People(String name, int age) {
          this.name = name;
              this.age = age;
      }
      public int getAge() {
          return age;
      } 
      public String getName() {
          return name;
      } 
      public void setAge(int age) {
          this.age = age;
      } 
      public void setName(String name) {
          this.name = name;
      }
      public void speak() {
        System.out.println(getName() + " " + getAge());
     }
}
 
public class Student extends People {
  private int grade;
  public Student(String name, int age) {    
    super(name, age);  
  }
  public Student(String name, int age, int grade) {
    super(name, age);            
    this.grade = grade;  
  }      
  public int getGrade() {   
    return grade;  
  }     
  public void setGrade(int grade) {   
    this.grade = grade;  
  }    
  private void learn(String course) {    
    System.out.println(name + " learn " + course);  
  }
}

Get the Class object through the class name

If you know a class at compile time name, we can get its Class object like this:

Class<People> peopleClass = People.class;

There is also a method to get the Class object based on the full path name of the class as follows:

//假设People类在com.test包中
Class<People> peopleClass = Class.forName("com.test.People");

Note that Class.forName() The method parameter must be the full pathname of a class. In fact, as long as we "import com.test.People", we can directly obtain his Class object through "People.class" without the trouble of writing out the full path. (If the corresponding class is not found on the classpath when calling the Class.forName() method, ClassNotFoundException will be thrown.)

Get the Class object through the object itself

People people = new People("Bill", 18);
Class<People> peopleClass = people.getClass();

Get the class through reflection The constructor

Once we obtain the Class object of People, we can obtain the original definition information of the People class through this Class object. First, let's get the constructor object of the People class. With this constructor object, we can construct a People object. For example, we can add the following code to Student.java:

public static void main(String[] args) {   
  Class<People> pClass = People.class;   
  try {   
    Constructor<People> constructor = pClass.getConstructor(String.class, int.class);     
    People people = constructor.newInstance("Bill", 18);                 
    people.speak();  
  } catch (Exception e) {  
  } 
}

Above, we call the getConstructor method to obtain a constructor object of the People class, because the formal parameter type of the constructor we want to obtain is String and int, so we pass in String.class and int.class. With the constructor object, we can call the newInstance method to create a people object.

Note that after obtaining the Constructor, Method, and Field objects of a class through reflection, before calling the methods of these objects, first set the accessible flag of this object to true to cancel the Java language access check. You can Increase reflection speed. As shown in the following code:

Constructor<People> constructor = peopleClass.getConstructor(String.class, 
    int.class);
// 设置 constructor 的 Accessible属性为ture以取消Java的访问检查
constructor.setAccessible(true);

Get the methods declared in the class through reflection

Get the methods declared in the current class (excluding those inherited from the parent class)

To get all the methods declared in the current class, you can use the getDeclaredMethods function in Class. It will get all the methods declared in the current class (including private, public, static, etc.), and it will return an array of Method objects, where Each Method object represents a method declared in a class. To get the specified method, you can call getDeclaredMethod(String name, Class...8742468051c85b06f0a0af9e3e506b5c parameterTypes). As shown in the following code:

private static void showDeclaredMethods() {  
  Student student = new Student("Bill", 18);   
  //获取Student类声明的所有方法 
  Method[] methods = student.getClass().getDeclaredMethods();       
   try {      
      //获取learnMethod对象(封装了learn方法) 
      Method learnMethod = student.getClass().getDeclaredMethod("learn", 
          String.class);                
      //获取learn方法的参数列表并打印出来 
      Class<?>[] paramClasses = learnMethod.getParameterTypes() ;        
      for (Class<?> class : paramClasses) {      
        System.out.println("learn方法的参数: " + class.getName());    
      }                
      //判断learn方法是否为private 
      System.out.println(learnMethod.getName() + " is private " 
          + Modifier.isPrivate(learnMethod.getModifiers()));   
      //调用learn方法    
      learnMethod.invoke(student, "Java Reflection");  
    } catch (Exception e) {  
  }
}

Get the public methods declared in the current class and the parent class

To get all the public methods declared in the current class and the parent class, you can call the getMethods function, and to To obtain a specified public method, you can call the getMethod method. Please look at the following code:

private static void showMethods() { 
  Student student = new Student("mr.simple");    
  // 获取所有public方法(包括Student本身的和从父类继承来的)  
  Method[] methods = student.getClass().getMethods();   
  try {    
    //注意,通过 getMethod只能获取public方法,若尝试获取private方法则会抛出异常 
    Method learnMethod = student.getClass().getMethod("learn", String.class);
  } catch (Exception e) {  
  }
}

Get the properties defined in the class through reflection

Getting properties is similar to getting methods, except that the call to getMethods() / getDeclaredMethods() method is replaced Becomes a call to the getFields() / getDeclaredFields() method.

Get the attributes defined in the current class (excluding attributes inherited from the parent class)

To get all the attributes defined in the current class (including private, public, static and other attributes ) You can call the getDeclaredFields function of the Class object; to obtain the specified attributes, you can call getDeclaredField. As shown in the following code:

private static void showDeclaredFields() {   
  Student student = new Student("Bill", 18);    
  // 获取当前类中定义的所有属性  
  Field[] fields = student.getClass().getDeclaredFields();   
  try {    
    // 获取指定的属性 
    Field gradeField = student.getClass().getDeclaredField("grade"); 
    // 获取属性值 
    System.out.println("The grade is : " + gradeField.getInt(student));    
    // 设置属性值    
    gradeField.set(student, 10); 
   } catch (Exception e) { 
  } 
}

Get the public properties defined in the current class and the parent class

To get all the public properties defined in the current class and the parent class, you can call the getFields function of the Class object , and to obtain a specified public attribute, you can call the getField method, as shown in the following code:

private static void showFields() {  
  Student student = new Student("Bill", 18);            
  // 获取当前类和父类的所有public属性 
  Field[] publicFields = student.getClass().getFields();        
}

Get the parent class of the class and the interface implemented by the class through reflection

获取父类

调用Class对象的getSuperClass方法即可,如以下代码所示:

Student student = new Student("Bill", 18);
Class<?> superClass = student.getClass().getSuperclass();

获取所实现的接口

要知道一个类实现了哪些接口,只需调用Class对象的getInterfaces方法,如以下代码所示:

private static void showInterfaces() { 
  Student student = new Student("Bill", 19); 
  Class<?>[] interfaces = student.getClass().getInterfaces();
}

The above is the detailed content of How to understand java reflection. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn