1 what is reflection?
Reflection is one of the features of Java programming language. It allows running Java programs to check themselves, or "self-examination", also known as "introspection".
Reflection is so powerful that it can even directly manipulate the private properties of the program. We all learned a concept earlier. Resources encapsulated by private can only be accessed inside the class, but not outside. However, this provision is completely broken by reflection.
Reflection is like a mirror. It can get all the information of a class at run time, get any defined information (including member variables, member methods, constructors, etc.), and manipulate the fields, methods, constructors, etc. of the class.
2 why reflection?
If you want to create an object, we can directly new User(); It's not very convenient. Why create objects through reflection?
Then I'll ask you a question first. Why do you go to a restaurant?
For example: we want to have a steak dinner. If we create it ourselves, we have to manage everything.
The advantage is that I'm very clear about what to do at every step, and the disadvantage is that I have to realize everything by myself. It's not dead tired. Cow delivery you tube, eat you tube, slaughter you tube, transport you tube, refrigerate you tube, cook you tube, serve you tube. Take cooking as an example. Can you have a top chef do it well?
Then what shall I do? There is a saying that professional things are done by professional people, raised by farmers, slaughtered by executioners, and cooked by special chefs. What are we doing?
Let's just cross our legs and bring it directly to eat.
Moreover, the restaurant should not throw things on the ground. Let's pick them up and eat. They are not all primitive people. Then what shall I do? It's very simple. Put the prepared things in a container, such as steak on a plate.
In the later study, we will learn about the framework. One framework, Spring, is a very professional and powerful product, which can help us create and manage objects. In the future, I can get the new object directly from the Beans in the container provided by Spring without manually. The bottom layer of Beans is actually a map < string, Object >, which is finally obtained through getBean("user"). The core implementation is the use of reflection technology.
To sum up, the class is not created by you, but by your colleagues or directly by a third-party company. At this time, if you want to call the underlying functions of this class, you need to implement reflection technology. It's a little abstract. Don't worry. Let's make a case and you'll be clear immediately.
3. API required for reflection
3.1 get bytecode object
Class.forName("full path of class");
Class name class
Object getClass();
3.2 common methods
Get package name class name
clazz.getPackage().getName() / / package name
clazz.getSimpleName() / / class name
clazz.getName() / / full class name
Get member variable definition information
getFields() / / get all exposed member variables, including inheritance variables
Getdeclaraedfields() / / get the member variables defined by this class, including private variables but excluding inherited variables
Getfield (variable name)
Getdeclaraedfield (variable name)
Get construction method definition information
Getconstructor (parameter type list) / / get the exposed constructor
getConstructors() / / get all the exposed construction methods
Getdeclaraedconstructors() / / get all construction methods, including private ones
getDeclaredConstructor(int.class,String.class)
Get method definition information
getMethods() / / get all visible methods, including inherited methods
Getmethod (method name, parameter type list)
getDeclaredMethods() / / get the methods defined by this class, including private methods and excluding inherited methods
Getdeclaraedmethod (method name, int.class,String.class)
Reflect new instance
clazz.newInstance();// Execute parameterless construction to create objects
clazz.newInstance(666, "SpongeBob")// Execute parametric construction to create objects
clazz.getConstructor(int.class,String.class) / / get the constructor
Reflection call member variable
clazz. Getdeclaraedfield (variable name)// Get variable
clazz.setAccessible(true);// Allow access to private members
f. Set (instance, value)// Assign a value to the variable of the specified instance, static variable, and the first parameter is null
f. Get (instance)// Access the value of the specified instance variable, static variable, and the first parameter is null
Reflection calls member methods
Method m = Clazz. Getdeclaraedmethod (method name, parameter type list);
m.setAccessible(true);// Allow private methods to be called
m. Invoke (instance, parameter data)// Let the specified instance execute the method
4 Application of reflection
4.1 create: test material class
Create package: CN tedu. reflection
Create class: student java*
package cn.tedu.review; /*This class is used to review reflective materials*/ public class Student { //1. Define member variables private String name; public int age; //2. Provide get and set methods for encapsulated attributes public String getName() { return name; } public void setName(String name) { this.name = name; } //3. Generate nonparametric and fully parametric structures of this class public Student(){} public Student(String name, int age) { this.name = name; this.age = age; } //4. Provide common methods for this class public void play(){ System.out.println("Today's finale, I'm going to write 1 after school W Line code play~"); } public void sunDay(int n){ System.out.println("National Day"+n+"day"); } //5. To view the specific properties and property values of the student object, rewrite toString() @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
4.2 exercise: getting class objects
Create package: CN tedu. reflection
Create class: testreflect java
package cn.tedu.reflection; import org.junit.Test; import java.lang.reflect.Method; import java.util.Arrays; /*This class is used for reflection testing*/ public class TestReflect { //1. Create the program's entry function main() -- No /*Unit test method: it is the smallest test unit in Java. It is flexible to use. Recommendation Index: 5 stars * Syntax requirements: @ Test + public + void + no parameters * Note: import package is required when using: Add JUnit 4 library to the build path * Effect after package Guide: import org junit. Test * Execution method: select the green triangle in front of the method name, and there will be a green check mark for successful operation * */ //2. Obtain the bytecode object corresponding to the target class Student through the unit test method @Test public void getClazz() throws ClassNotFoundException { //Practice 3 ways to get bytecode objects Class<?> clazz1 = Class.forName("cn.tedu.review.Student"); Class<?> clazz2 = Student.class; Class<?> clazz3 = new Student().getClass(); //The bytecode object corresponding to the Student class is printed System.out.println(clazz1);//class cn.tedu.reflection.Student //Gets the name of the current bytecode object clazz1 System.out.println(clazz1.getName());//cn.tedu.reflection.Student //Get the class name of Student class through bytecode object System.out.println(clazz2.getSimpleName()); //Obtain the package object corresponding to the Student class through the bytecode object System.out.println(clazz3.getPackage()); //Through the bytecode object, first obtain the package object corresponding to the Student class, and then obtain the name of the package object System.out.println(clazz3.getPackage().getName()); }
4.3 exercise: getting member variables
package cn.tedu.reflection; import java.lang.reflect.Field; import org.junit.Test; /**This class is used to test reflection*/ public class TestReflect { //3. Practice the definition and traversal of reference type array through unit test method @Test public void getStu() { //1. Create three objects of Student class Student s1 = new Student("Zhang San", 3); Student s2 = new Student("Li Si", 4); Student s3 = new Student("Wang Wu", 5); //2. Create an array and store the three objects in the array Student[] s = {s1, s2, s3}; //3. Print the array directly and view the elements in the array System.out.println(Arrays.toString(s)); //4. Traverse the student array, get each student object and do further operations for (Student stu : s) { //System.out.println(stu); stu.play();//Execute play() by traversing the object System.out.println(stu.age);//Print the age attribute by traversing the object } } //4. Obtain the member variables in the Student class through the unit test method @Test public void getFie() throws ClassNotFoundException { //1. Get bytecode object Class<?> clazz = Class.forName("cn.tedu.review.Student"); //2. Get member variables through bytecode object Field[] fs = clazz.getFields(); //3. Traverse the array to get the specific information of each member variable /*be careful! Currently, the modifier of a member variable can only be obtained if it is public. Otherwise, the default modifier cannot be obtained*/ for(Field f : fs){ System.out.println(f.getName());//Get the field name through the field object to which this round loops System.out.println(f.getType());//Get the type of the field through the field object to which this round loops } } }
4.5 exercise: get the construction method of class through bytecode object
package cn.tedu.reflection; import java.lang.reflect.Constructor; import java.util.Arrays; import org.junit.Test; /**This class is used to test reflection*/ public class TestReflect { //6. Obtain the construction method in the Student class through the unit test method @Test public void getCons() { //1. Get bytecode object Class<?> clazz = new Student().getClass(); //2. Obtain the construction method of the target class Student through the bytecode object Constructor<?>[] cs = clazz.getConstructors(); //3. Traverse the array through an efficient for loop for(Constructor c : cs){ System.out.println(c.getName());//Print the name of the construction method traversed in this round Class[] pt = c.getParameterTypes();//Get the parameter type of the constructor through the constructor object traversed in this round System.out.println(Arrays.toString(pt));//Print parameter type } }
4.6 exercise: creating objects
package cn.tedu.reflection; import java.lang.reflect.Constructor; import org.junit.Test; /**This class is used to test reflection*/ public class TestReflect { //7. Create the object of the Student target class through the unit test method @Test public void getObject() throws Exception { //1. Get bytecode object Class<?> clazz = Student.class; //2. Create the object of the target class through reflection technology, and pay attention to throwing exceptions /*Reflection object creation scheme 1: create an object by triggering the parameterless construction of the target class*/ Object o = clazz.newInstance(); System.out.println(o);//In this step, the object Student{name='null', age=0} has been obtained /*Reflection object creation scheme 2: create an object by triggering the full parameter construction of the target class * Idea: * 1.Get the specified constructor object first. Note that you need to specify the parameters of the constructor. What is passed in is class bytecode object * 2.Create the object of the Student target class through the constructor object just obtained, and assign a value to the property of the object * */ //3. Get the full parameter construction specified in the target class Constructor<?> c = clazz.getConstructor(String.class, int.class); //System.out.println(c); //4. Through the obtained constructor: create object + assign value to the attribute of the object Object o2 = c.newInstance("Zhao Liu", 6); System.out.println(o2); } }
4.7 familiar with API
Create your own class exercise, get all the resources in the class, and be familiar with the API s involved in reflection
5 violent reflex
It refers to that private attributes or methods in the program can be obtained violently through reflection technology. Common methods to use are as follows:
5.1 create: test material class
Create package: CN tedu. reflection
Create class: person java*
package cn.tedu.review; /*This class is used as material for violent reflection test*/ public class Person { //1. Provide private attributes private String name; private int age; //2. Provide private methods private void save(int n,String s){ System.out.println("save()..."+n+s); } private void update(){ System.out.println("update()..."); } }
5.2 exercise: creating a test class
Create package: CN tedu. reflection
Create class: testreflect2 java
package tedu.reflection; import org.junit.Test; import java.lang.reflect.Field; import java.lang.reflect.Method; /*This class is used to test violent reflex*/ public class TestReflect2 { /*1.Get and manipulate properties through violent reflection*/ @Test public void getFie2() throws Exception { //1. Get bytecode object Class<?> clazz = Person.class; //2. Get the specified private property. The property name is passed in. Note that an exception is thrown Field field = clazz.getDeclaredField("name"); //3. View the attribute information according to the attribute object just obtained System.out.println(field);//Print the obtained field object directly System.out.println(field.getType().getName());//java.lang.String System.out.println(field.getType());//class java.lang.String //4. Set the value of the attribute //4.1 you need to specify which object's name attribute is set to. If there is no object, create the object Object obj = clazz.newInstance();//Trigger parameterless construction to create objects using reflection //4.2 violent reflection, private visible permission needs to be set!!! field.setAccessible(true); //4.3 set the attribute value of the newly created object obj as SpongeBob through the field object //field is the name attribute we just obtained //set(m,n)--m is the value set for the name attribute of which object, and N is the value set field.set(obj,"Spongebob"); //4.4 print and view the attribute value just set //field.get(m)--field represents the name attribute of the Person class. M is the attribute value of which object to view System.out.println(field.get(obj)); } //2. Define the unit test method and use violent reflection to operate the private attribute age in the Person class [consolidation exercise] @Test public void getFie3() throws Exception { //1. Get bytecode object Class<?> clazz = Person.class; //2. Get the specified private property object Field f = clazz.getDeclaredField("age"); //3. View relevant information, such as attribute type, according to the obtained attribute object System.out.println(f.getType().getName()); //4. Operation: set attribute value: three elements are required: what value is set for which attribute [2] of which object [1] [3] //4.1 you need to set the value of this age attribute to which object you want to assign first Object obj = clazz.newInstance(); //4.2 before setting the value for the attribute, you need to set the permission private visible, otherwise an error will be reported! f.setAccessible(true); //4.3 set the value of obj object through the age attribute object just obtained f.set(obj,17); //4.4 print and check whether the attribute value just set is successful System.out.println(f.get(obj)); } /*3.Unit test 2: get and set private methods*/ @Test public void getFunction() throws Exception { //1. Get Class bytecode object Class<?> clazz = Person.class; //2. Methods of obtaining private information through violent reflection /*getDeclaredMethod(m,x,y,z...) * m:Method name to get * x,y,z...Variable parameter is the parameter type of this method, but note that ". class" should be added * */ Method method = clazz.getDeclaredMethod("save",int.class,String.class); //3.1 create objects by reflection without objects Object obj = clazz.newInstance(); //3.2 to execute private methods, you also need to set private visibility first method.setAccessible(true); /*invoke(o,x,y,z...),Represents a method performed by reflection technology * o :Which object's method is to be executed * x,y,z...:Parameters to be passed in when executing this method [previously obtained save(), represented by method object] * */ //3.3 execute the target method [save()] of the target object obj through the reflection technology invoke() //When save() is called, the parameter passed in is 100, "SpongeBob" method.invoke(obj,100,"Spongebob"); } }
Congratulations, you have learned a new knowledge. There are many reflection API s. You should practice more