1. Introduction
Java reflection is a mechanism that allows us to obtain internal information of class 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 built by the Java virtual machine based on Class object of this class at runtime, and reflection is to obtain its definition information through Class object of a class, so that we can access its properties and methods, know the parent class of this class, which interfaces are implemented, and other information.
2. Class
We know that using javac can compile .java files into .class files, which contain our original definition information for the class (parent class, interface, constructor, properties, methods, etc.). The .class file will be loaded into the Java virtual machine (JVM) ClassLoader at runtime. When a .class file is loaded, the JVM will generate a Class object for it. The objects we instantiate through new in the program are actually constructed based on the corresponding Class object at runtime. To be precise, this Class object is actually an instance of java.lang.Class<T> generic class. For example, Class<MyClass> object is a Class<T> instance that encapsulates the definition information of MyClass class. Since java.lang.Class<T> class does not have a public constructor, we cannot instantiate this class directly. We can get a Class object through the following method.
In the following explanation, we will take the People class and 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 Class object by class name
If we know the name of a class during the compilation period, we can get its Class object like this:
Class<People> peopleClass = People.class;
There is also a method to obtain Class objects based on the full path name of the class as follows:
//Suppose that the People class is in the com.test package Class<People> peopleClass = Class.forName("com.test.People"); Note that the parameter of Class.forName() method must be the full path name of a class. In fact, as long as we "import com.test.People", we can directly obtain its Class object through " People.class " without having to write out the full path. (If the corresponding class is not found in classpath when calling Class.forName() method, ClassNotFoundException will be thrown.)
Get its Class object through the object itself
People people = new People("Bill", 18);Class<People> peopleClass = people.getClass(); Get the constructor of the class by reflection
Once we have obtained People 's Class object, we can obtain the original definition information of People class through this Class object. First, let’s get the constructor object of People class. With this constructor object, we can construct a People object. For example, we can add the following code in 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); obj.speak(); } catch (Exception e) { } } In the above, we call getConstructor method to get a constructor object of People class. Since the constructor we want to get the formal parameters of the type String and int , 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 when the class's Constructor , Method , and Field objects are obtained through reflection, before calling the methods of these objects, the accessible flag of this object is set to true to cancel the Java language access check, which can improve the reflection speed. As shown in the following code:
Constructor<People> constructor = peopleClass.getConstructor(String.class, int.class);// Set the Accessible property of constructor to ture to cancel Java access check constructor.setAccessible(true);
Getting methods declared in class through reflection
Get the declared method in the current class (excluding inherited from the parent class)
To get all methods declared in the current class, you can use the getDeclaredMethods function in Class. It will get all methods declared in the current class (including private , public , static and other methods). It will return an array of Method objects, and each Method object represents the method declared in a class. To get the specified method, you can call getDeclaredMethod(String name, Class...<T> parameterTypes) .
As shown in the following code:
private static void showDeclaredMethods() { Student student = new Student("Bill", 18); //Get all methods declared by the Student class Method[] methods = student.getClass().getDeclaredMethods(); try { //Get the learnMethod object (encapsulated the learn method) Method learnMethod = student.getClass().getDeclaredMethod("learn", String.class); //Get the parameter list of the learn method and print it out Class<?>[] paramClasses = learnMethod.getParameterTypes() ; for (Class<?> class : paramClasses) { System.out.println("learn method parameters: " + class.getName()); } //Judge whether the learn method is private System.out.println(learnMethod.getName() + " is private " + Modifier.isPrivate(learnMethod.getModifiers())); //Call the learn method learnMethod.invoke(student, "Java Reflection"); } catch (Exception e) { }} Get public methods declared in the current class and the parent class
To get the current class and all public methods declared in the parent class, you can call the getMethods function, and to get a specified public method, you can call the getMethod method. Please see the following code:
private static void showMethods() { Student student = new Student("mr.simple"); // Get all public methods (including Student itself and inherited from the parent class) Method[] methods = student.getClass().getMethods(); try { //Note that only public methods can be obtained through getMethod. If you try to get private method, an exception will be thrown. Method learnMethod = student.getClass().getMethod("learn", String.class); } catch (Exception e) { }} Get the attributes defined in the class by reflection
Getting attributes is similar to getting methods, except that the call to getMethods() / getDeclaredMethods() methods is replaced with a call to getFields() / getDeclaredFields() methods.
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 various attributes such as private , public , static , etc.), 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); // Get all attributes defined in the current class Field[] fields = student.getClass().getDeclaredFields(); try { // Get the specified attribute Field gradeField = student.getClass().getDeclaredField("grade"); // Get the attribute value System.out.println("The grade is : " + gradeField.getInt(student)); // Set the attribute value gradeField.set(student, 10); } catch (Exception e) { } } Get the public attributes defined in the current class and the parent class
To get all public properties defined in the current class and the parent class, you can call the getFields function of Class object. To get a specified public property, you can call getField method, as shown in the following code:
private static void showFields() { Student student = new Student("Bill", 18); // Get all public properties of the current class and parent class Field[] publicFields = student.getClass().getFields(); } Reflection to obtain the parent class of the class and the interface implemented by the class
Get the parent class
Just call the getSuperClass method of Class object, as shown in the following code:
Student student = new Student("Bill", 18);Class<?> superClass = student.getClass().getSuperclass(); Get the implemented interface
To know which interfaces a class implements, just call the getInterfaces method of Class object, as shown in the following code:
private static void showInterfaces() { Student student = new Student("Bill", 19); Class<?>[] interfaces = student.getClass().getInterfaces();}Summarize
The above is the entire content of this article. I hope it will be helpful to everyone's study and work.