reflex
1. Class loader
1.1 loading of class
When a program wants to use a class, if the class has not been loaded into memory, the system will initialize the class through three steps: loading, connecting and initialization.
-
load
This is to read the class file into memory and create a class object for it.
When any Class is used, the system will create a Class object
-
connect
Verify whether there is a correct internal structure and is consistent with other classes
Preparation is responsible for allocating memory for static members of the class and setting default initialization values
-
Parsing replaces the symbolic reference in the binary data of the class with a direct reference
-
initialization
This is the initialization step we talked about before
1.2 initialization timing
-
Create an instance of a class
-
Class, or assign a value to a static variable
-
Class
-
Use reflection to force the creation of java.lang.Class objects corresponding to a class or interface
-
Initializes a subclass of a class
-
Directly use the java.exe command to run a main class
Class 1.3 loader
It is responsible for loading the. Class file into the internal and generating the corresponding class object for it.
Although we don't need to care about the class loading mechanism, we can better understand the operation of the program by understanding this mechanism
Composition of class 1.4 loader
Bootstrap ClassLoader root classloader
Also known as boot class loader, it is responsible for loading Java core classes
For example, System,String, etc. In the JDK, in the rt.jar file under the lib directory of JRE
Extension ClassLoader extension classloader
Be responsible for loading jar packages in JRE's extension directory.
In the JDK, the ext directory is under the lib directory of JRE
System ClassLoader
It is responsible for loading the class file from the java command and the jar package and classpath specified by the classpath environment variable when the JVM starts.
Through these descriptions, we can know who loads the commonly used classes.
So far, we know how to load class files into memory. If we only stand on the perspective of these class files, how can we use the contents of these class files? This is what we want to study.
2. Reflection mechanism
java reflection mechanism is to know all the properties and methods of any class in the running state; For any object, you can call any of its methods and properties; This kind of dynamically acquired information and the function of dynamically calling object methods are called the reflection mechanism of java language.
To dissect a Class, you must first obtain the bytecode file object of the Class. The anatomy uses the methods in the Class class, so we must first obtain the Class type object corresponding to each bytecode file.
2.1 Class
After reading the Class class of API, we know that Class has no public constructor. The Class object is automatically constructed by the Java virtual machine and by calling the defineClass method in the Class loader when the Class is loaded
l three ways to obtain Class objects
Method 1: use the getObject() method in the Object class
Person p = new Person(); Class c = p.getClass();
Method 2: obtain the bytecode file object through the class name. Class (any data type has a class static attribute, which looks simpler than the first method).
Class c2 = Person.class;
Method 3: through the method in Class (just pass the Class name as a string to the static method forName in Class).
Class c3 = Class.forName("Person");
l note: the difference between the third and the first two
In the first two, you must specify the Person type
This extension is stronger. I don't need to know your class. I only provide strings and load them according to the configuration file
/* * How to get the. class bytecode file object * 1: Through the getObject() method in the Object class * 2: Get bytecode file object through class name. Class * 3: Methods in reflection, * public static Class<?> forName(String className) throws ClassNotFoundException * Returns the Class object associated with the Class or interface with the given string name */ public class ReflectDemo { public static void main(String[] args) throws ClassNotFoundException { // 1: Through the getObject() method in the Object class // Person p1 = new Person(); // Class c1 = p1.getClass(); // System.out.println("c1 = "+ c1); // 2: Get bytecode file object through class name. Class // Class c2 = Person.class; // System.out.println("c2 = "+ c2); // 3: Methods in reflection Class c3 = Class.forName("cn.itcast_01_Reflect.Person");// Package name. Class name System.out.println("c3 = " + c3); } }
Person class package cn.itcast_01_Reflect; public class Person { //Member variable public String name; public int age; private String address; //Construction method public Person() { System.out.println("Null parameter construction method"); } public Person(String name) { this.name = name; System.out.println("have String Construction method of"); } //Private construction method private Person(String name, int age){ this.name = name; this.age = age; System.out.println("have String,int Construction method of"); } public Person(String name, int age, String address){ this.name = name; this.age = age; this.address = address; System.out.println("have String, int, String Construction method of"); } //Member method //Method with no return value and no parameters public void method1(){ System.out.println("Method with no return value and no parameters"); } //Method with no return value and parameters public void method2(String name){ System.out.println("Method with no return value and parameters name= "+ name); } //There are return values and no parameters public int method3(){ System.out.println("Method with return value and no parameters"); return 123; } //Methods with return values and parameters public String method4(String name){ System.out.println("Methods with return values and parameters"); return "ha-ha" + name; } //Private method private void method5(){ System.out.println("Private method"); } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", address=" + address+ "]"; } }
2.2 obtain the construction method by reflection and use it
In the reflection mechanism, the members in the Class (Constructor, member method and member variable) are encapsulated into corresponding classes for representation. The construction method is represented by the Class Constructor. The construction method can be obtained through the method provided in Class:
-
Returns a constructor
Public constructor getconstructor (class <? >... parameterTypes) gets the public modifier and specifies the construction method corresponding to the parameter typePublic constructor getdeclaraedconstructor (class <? >... parameterTypes) gets the constructor (including private) corresponding to the specified parameter type
-
Returns multiple constructor methods
public Constructor<?> [] getconstructors() get the constructor of all public modifiers
public Constructor<?> [] getdeclaraedconstructors() get all construction methods (including private ones)
public class ReflectDemo { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException { //Get Class object Class c = Class.forName("cn.itcast_01_Reflect.Person");//Package name. Class name //Get all construction methods //Constructor[] cons = c.getConstructors(); Constructor[] cons = c.getDeclaredConstructors(); for (Constructor con : cons) { System.out.println(con); } System.out.println("------------------------"); //Get a constructor //public Person() Constructor con1 = c.getConstructor(null); System.out.println(con1); //public Person(String name) Constructor con2 = c.getConstructor(String.class); System.out.println(con2); //private Person(String name, int age) Constructor con3 = c.getDeclaredConstructor(String.class, int.class); System.out.println(con3); //public Person(String name, int age, String address) Constructor con4 = c.getDeclaredConstructor(String.class, int.class, String.class); System.out.println(con4); } }
2.3 obtain the construction method and create objects through reflection
To obtain the construction method, the steps are as follows:
-
Get Class object
-
Gets the specified construction method
-
Create objects by constructing methods in the method class Constructor
public T newInstance(Object... initargs)
Code demonstration
-
public class ConstructorDemo { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //1. Get Class object Class c = Class.forName("cn.itcast_01_Reflect.Person");//Package name. Class name //2. Obtain the specified construction method //public Person() //Constructor con = c.getConstructor(null); //public Person(String name, int age, String address) Constructor con = c.getConstructor(String.class, int.class, String.class); //3. Create an object by constructing the Constructor method in the method class //Object obj = con.newInstance(null); Object obj = con.newInstance("Xiao Ming", 22, "Harbin"); //display System.out.println(obj); } }
2.3 obtain private construction methods and create objects through reflection
The AccessibleObject class is the parent class of Field, Method, and Constructor objects. It provides the ability to mark reflected objects to cancel the default Java language access control check when used.
For public members, default (packaged) access members, protected members and private members, access checks are performed when Field, Method or Constructor objects are used to set or obtain fields, call methods, or create and initialize new instances of classes, respectively. Common methods are as follows:
public void setAccessible(boolean flag) throws SecurityException
If the parameter value is true, it indicates that the Java language access check should be cancelled when the reflected object is used. If the parameter value is false, it indicates that the reflected object should implement Java language access check.
To obtain the private construction method, the steps are as follows:
-
Get Class object
-
Gets the specified construction method
-
Violent access through setAccessible(boolean flag) method
-
Create objects by constructing methods in the method class Constructor
public T newInstance(Object... initargs)
public class ConstructorDemo2 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //1. Get Class object Class c = Class.forName("cn.itcast_01_Reflect.Person");//Package name. Class name //2. Obtain the specified construction method //private Person(String name, int age) Constructor con = c.getDeclaredConstructor(String.class, int.class); //3. Violent reflex con.setAccessible(true);//Cancel Java language access check //4. Create objects by constructing the functions in the method class Object obj = con.newInstance("Xiao Ming", 23); System.out.println(obj); } }
2.4 get member variables through reflection and use
In the reflection mechanism, the member variables in the Class are represented by the Class Field. Member variables can be obtained through the methods provided in Class:
Returns a member variable
public Field getField(String name) gets the specified public modified variable
Public field getdeclaraedfield (string name) gets any specified variable
Returns multiple member variables
public Field[] getFields() gets all public modified variables
Public field [] getdeclaraedfields() get all variables (including private)
public class FieldDemo { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException { //Get Class object Class c = Class.forName("cn.itcast_01_Reflect.Person"); //Get member variable //Multiple variables //Field[] fields = c.getFields(); Field[] fields = c.getDeclaredFields(); for (Field field : fields) { System.out.println(field); } System.out.println("-----------------"); //A variable //public int age; Field ageField = c.getField("age"); System.out.println(ageField); //private String address Field addressField = c.getDeclaredField("address"); System.out.println(addressField); } }
2.5 create objects through reflection, obtain specified member variables, and perform assignment and value acquisition operations
To obtain the member variable, the steps are as follows:
-
Get Class object
-
Get construction method
-
Create objects through construction methods
-
Get the specified member variable (private member variable, accessed through setAccessible(boolean flag) method)
-
Assign a value or get a value to the specified member variable of the specified object through the method
public void set(Object obj, Object value)
In the specified object obj, set the member variable represented by this Field object to the specified new value
public Object get(Object obj)
Returns the value of the member variable represented by this Field object in the specified object obj
public class FieldDemo2 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException { //1. Get Class object Class c = Class.forName("cn.itcast_01_Reflect.Person"); //2. Obtain the construction method //public Person(String name) Constructor con = c.getConstructor(String.class); //3. Create objects through construction methods Object obj = con.newInstance("Xiao Ming"); //4. Get the specified member variable //public String name; Field nameField = c.getField("name"); //public int age; Field ageField = c.getField("age"); //private String address; Field addressField = c.getDeclaredField("address"); addressField.setAccessible(true); //Cancel Java language access check //5. Assign a value or obtain a value to the specified member variable of the specified object through the method System.out.println("name = "+ nameField.get(obj)); System.out.println("age = "+ ageField.get(obj)); System.out.println("address = "+ addressField.get(obj)); //assignment ageField.set(obj, 23); addressField.set(obj, "Kelly square"); System.out.println("------------------------"); System.out.println("name = "+ nameField.get(obj)); System.out.println("age = "+ ageField.get(obj)); System.out.println("address = "+ addressField.get(obj)); } }
2.6 get member method through reflection and use
In the reflection mechanism, the member methods in the Class are represented by Class Method. Member methods can be obtained through the methods provided in Class:
Return to get a method:
public Method getMethod(String name, Class<?>... parameterTypes)
Method to get public modifier
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
Get any method, including private
Parameter 1: name: name of the method to find; Parameter 2: parameterTypes the parameter type of the method
Return to get multiple methods:
public Method[] getMethods() gets the methods of all public modifications in this class and its parent class
public Method[] getDeclaredMethods() gets all the methods in this class (including private ones)
public class MethodDemo { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException { //Get Class object Class c = Class.forName("cn.itcast_01_Reflect.Person"); //Get multiple methods //Method[] methods = c.getMethods(); Method[] methods = c.getDeclaredMethods(); for (Method method : methods) { System.out.println(method); } System.out.println("-----------------------"); //Get a method: //public void method1() Method method = c.getMethod("method1", null); System.out.println(method); //public String method4(String name){ method = c.getMethod("method4", String.class); System.out.println(method); //Private method //private void method5() method = c.getDeclaredMethod("method5", null); System.out.println(method); } }
2.7 create objects and call specified methods through reflection
To obtain the member method, the steps are as follows:
-
Get Class object
-
Get construction method
-
Create objects through construction methods
-
Gets the specified method
-
Execute the method found
public Object invoke(Object obj, Object... args)
Execute the Method represented by the current Method object in the specified object obj, and the parameters to be passed in by the Method are specified through args.
Code demonstration:
public class MethodDemo2 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //1. Get Class object Class c = Class.forName("cn.itcast_01_Reflect.Person"); //2. Obtain the construction method //public Person(String name, int age, String address){ Constructor con = c.getConstructor(String.class, int.class, String.class); //3. Create objects through construction methods Object obj = con.newInstance("Xiao Ming", 23, "Harbin"); //4. Get the specified method //public void method1() has no method with return value and no parameters //Method m1 = c.getMethod("method1", null); //public String method4(String name) Method m4 = c.getMethod("method4", String.class); //5. Execute the method found //m1.invoke(obj, null); Object result = m4.invoke(obj, "itcast"); System.out.println("result = " + result); } }
2.8 create an object through reflection and call the specified private method
To obtain the private member method, the steps are as follows:
-
Get Class object
-
Get construction method
-
Create objects through construction methods
-
Gets the specified method
-
Open violent access
-
Execute the method found
public Object invoke(Object obj, Object... args)
Execute the Method represented by the current Method object in the specified object obj, and the parameters to be passed in by the Method are specified through args.
Code demonstration:
public class MethodDemo3 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //1. Get Class object Class c = Class.forName("cn.itcast_01_Reflect.Person"); //2. Obtain the construction method //public Person(String name, int age, String address){ Constructor con = c.getConstructor(String.class, int.class, String.class); //3. Create objects through construction methods Object obj = con.newInstance("Xiao Ming", 23, "Harbin"); //4. Get the specified method //private void method5(){ Method m5 = c.getDeclaredMethod("method5", null); //5. Open violent visit m5.setAccessible(true); //6. Execute the method found m5.invoke(obj, null); } }
3 reflection practice
3.1 generic erasure
Think about how to add a string data to the existing ArrayList collection?
Let me tell you that there are no generic constraints in the. class file generated after program compilation. This phenomenon is called generic erasure. Then, we can add any type of element to the collection with generic constraints through reflection technology
The code is as follows:
public class ReflectTest { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { ArrayList<Integer> list = new ArrayList<Integer>(); //Add element to collection list.add(new Integer(30)); list.add(new Integer("12345")); list.add(123); //list.add("ha ha")// Because there are constraints on generic types System.out.println(list); //Through reflection technology, arbitrary types of elements can be added //1. Get bytecode file object //Class c = list.getClass(); //Class c = ArrayList.class; Class c = Class.forName("java.util.ArrayList"); //2. Find the add() method // public boolean add(E e) Method addMethod = c.getMethod("add", Object.class); //3. Execute the add() method addMethod.invoke(list, "ha-ha");// list.add("ha ha"); System.out.println(list); } }
3.1 reflection profile
Run the corresponding method of the specified class in the configuration file through the reflection configuration file
Read the data in the people.txt file and complete the creation of the Person object through reflection technology
The contents of the people.txt file are as follows:
className=cn.itcast_01_Reflect.Person methodName=method5
Read the configuration file and call the corresponding method in the specified class
public class ReflectTest2 { public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { // Reading data from a file through the Properties collection Properties prop = new Properties(); // Read the data from the file into the collection prop.load(new FileInputStream("properties.txt")); // Gets the value corresponding to the key String className = prop.getProperty("className"); System.out.println(className); // 1. Get the Person.class bytecode file object Class c = Class.forName(className); // 2. Obtain the construction method // public Person(String name, int age, String address) Constructor con = c.getConstructor(String.class, int.class, String.class); // 3. Create object Object obj = con.newInstance("Xiao Ming", 20, "China"); System.out.println(obj); // 4. Get the specified method // private void method5(){} String methodName = prop.getProperty("methodName"); Method m5 = c.getDeclaredMethod(methodName, null); // 5. Open violent visit m5.setAccessible(true); // 6. Execute the method found m5.invoke(obj, null); } }