reflex
Basic introduction to reflection
-
Reflection can control the program through external file configuration without modifying the source code, which also conforms to the ocp principle of design mode (opening and closing principle: do not modify the source code, expansion function)
-
Reflection mechanism:
Reflection mechanism allows the program to obtain the internal information of any class (such as member variables, constructors, member methods, etc.) with the help of reflection API during execution, and can operate the properties and methods of objects. Reflection will be used at the bottom of design patterns and frameworks
After loading the Class, an object of Class type is generated in the heap (there is only one Class object in a Class). This object contains the complete structure information of the Class, and the structure of the Class is obtained through this object
-
The reflection mechanism can complete:
(1) Determine the class of any object at run time
(2) Construct an object of any class at run time
(3) Get the member variables and methods of any class at run time
(4) Call the member variables and methods of any object at run time
(5) Generate dynamic proxy
-
Reflection related classes:
(1)java.lang.Class: represents a Class, and the Class object represents the object in the heap after a Class is loaded
(2)java.lang.reflect.Method: represents the method of the class
(3)java.lang.reflect.Field: represents the member variable of the class
(4)java.lang.reflect.Constructor: represents the construction method of the class
These classes are in Java Lang.reflection package
-
Reflection can dynamically create and use objects, which can be used flexibly, but the prosperous use is basically to explain the execution, which has an impact on the execution speed
-
Reflection call Optimization:
(1)Method, Field and Constructor objects all have setAccessible() methods
(2)setAccessible is a switch that enables and disables access security checks
(3) If the parameter value is true, it means that the reflected object cancels the access check when in use to improve the reflection efficiency. If the parameter value is false, it means that the reflected object performs access check
Class class
-
Class class
(1)Class is also a class, so it inherits the Object class
(2)Class objects are not new, but created by the system
(3) For the Class object of a Class, there is only one copy in memory, because the Class is loaded only once
(4) Each Class instance will remember which Class instance it was generated from
(5) Through Class, you can get the complete structure of a Class through a series of API s
(6)Class objects are stored in the heap
(7) The bytecode binary data of a class is placed in the method area. In some places, it is called the metadata of the class (including method code, variable name, method name, access permission, etc.)
-
Class common methods
/** * Demonstrate common methods of Class */ public class ClassMethod { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException { String classAllPath = "class_.Car"; //1. Get the object corresponding to Car class Class<?> cls = Class.forName(classAllPath); System.out.println(cls);//Show cls object class_ Car System.out.println(cls.getClass());//Output cls run type Java lang.Class //2. Get package name System.out.println(cls.getPackage().getName()); //3. Get the full class name System.out.println(cls.getName()); //4. Create object instances through cls Object o = cls.newInstance();//You can create Object objects Car car = (Car)cls.newInstance();//You can also create Car objects System.out.println(car);//car.toString() //5. Acquire data through reflection Field f = cls.getField("brand"); System.out.println(f.get(car));//Private properties cannot be accessed //6. Assign values to attributes by reflection f.set(car,"Benz"); System.out.println(f.get(car)); //8. Get all attributes Field[] fields = cls.getFields(); for (Field field : fields){ System.out.println(field.getName()); } } }
-
Six ways to get Class objects
/** * Demonstrate how to get the Class object */ public class GetClass { public static void main(String[] args) throws ClassNotFoundException { //1. The full Class name of a Class is known, and the Class is under the Class path, which can be obtained through the static method forName() of Class //Application scenario: it is mostly used for configuration files, reading the full path of classes and loading classes String classAllPath = "class_.Car"; Class cls1 = Class.forName(classAllPath); System.out.println(cls1); //2. If a specific class is known, it can be obtained through the class of the class. This method is the most safe and reliable, and the program performance is the highest //Application scenario: it is mostly used for parameter transfer, such as obtaining the corresponding constructor object through reflection Class cls2 = Car.class; System.out.println(cls2); //3. If the instance of a Class is known, call the getClass() method of the instance to get the Class object //Application scenario: get the Class object by creating a good object Car car = new Car(); Class cls3 = car.getClass(); System.out.println(cls3); //4. The Class loader gets the Class object //(1) Get class loader ClassLoader classLoader = car.getClass().getClassLoader(); //(2) Get the Class object through the Class loader Class cls4 = classLoader.loadClass(classAllPath); System.out.println(cls4); //Cls1, cls2, cls3 and cls4 are actually the same object System.out.println(cls1.hashCode()); System.out.println(cls2.hashCode()); System.out.println(cls3.hashCode()); System.out.println(cls4.hashCode()); //Other ways //5. Get Class objects from basic data types Class<Integer> integerClass = int.class; Class<Character> characterClass = char.class; System.out.println(integerClass);//The bottom layer of output int has automatic packing and unpacking processes //6. The package Class corresponding to the basic data TYPE can be passed TYPE gets the Class object Class<Double> type = Double.TYPE; System.out.println(type);//Output double Class<Integer> type1 = Integer.TYPE; //The hashCode output below is the same System.out.println(integerClass.hashCode()); System.out.println(type1.hashCode()); } }
-
Which types have Class objects
(1) External class, member internal class, static internal class, local internal class, anonymous internal class
(2)interface: Interface
(3) Array
(4) Enumeration
(5)annotation: Annotation
(6) Basic data type
(7)void
(8)Class itself
Class loading
-
Class loading: reflection mechanism is the key to realize dynamic language in java, that is to realize dynamic class loading through reflection
(1) Static loading: load relevant classes during compilation. If not, an error will be reported, which is too dependent
(2) Dynamic loading: load the required class at runtime. If the class is not used at runtime, no error will be reported, reducing the dependency
-
Class loading time:
(1) When creating an object (new) (static load)
(2) When subclasses are loaded (static loading)
(3) When calling a static member in a class (static load)
(4) By reflection (dynamic loading)
-
Class loading phase:
(1) Loading:
At this stage, the JVM mainly converts the bytecode from different data sources (possibly class files, jar packages, or even the network) into binary byte streams, loads them into memory, and generates a Java. Java representing this class Lang.class object
(2) Linking phase:
1) Verification: the purpose is to ensure that the information contained in the byte stream of the Class file meets the requirements of the current virtual machine and will not endanger the safety of the virtual machine itself; Including file format verification (whether it starts with magic number oxcafebabe), metadata verification, bytecode verification and symbol reference verification; Consider using the - Xverify:none parameter to turn off most of the Class verification measures and shorten the loading time of virtual machine classes
2) Preparation: at this stage, the JVM will allocate memory and initialize static variables (not those modified by static final) (corresponding to the default initial values of data types, such as 0, null, false, etc.), and the memory used by these variables will be matched in the method area
3) Resolution: the process by which a virtual machine replaces a symbolic reference in a constant pool with a direct reference
(3) Initialization: the Java program code defined in the class will not be executed until the initialization stage. This stage is the process of executing the < clinit > () method< Clinit > () method is that the compiler automatically collects the assignment actions of all static variables in the class and the statements in the static code block according to the order in which the statements appear in the source file, and combines them; Virtual opportunity ensures that the < clinit > () method of a class is locked and synchronized correctly in a multithreaded environment. If multiple threads initialize a class at the same time, only one thread will execute the < clinit > () method of this class, and other threads need to block and wait until the active thread finishes executing the < clinit > () method
Reflection related operation
-
Get class structure information through reflection
public class ReflectionUtils { @Test //The first group is Java Lang. class class public void api_01() throws ClassNotFoundException { Class<?> personCls = Class.forName("reflection.Person"); //1. Get the full class name System.out.println(personCls.getName());//reflection.Person //2. Get the simple class name System.out.println(personCls.getSimpleName());//Person //3. Get the attributes of all public modifications, including the attributes of this class and its parent class Field[] fields = personCls.getFields(); for (Field field :fields) { System.out.println(field); } //4. Get all attributes in this class Field[] declaredFields = personCls.getDeclaredFields(); for (Field field :declaredFields) { System.out.println(field.getName()); } //5. Get all public modified methods, including the methods of this class and its parent class Method[] methods = personCls.getMethods(); for (Method method :methods) { System.out.println(method.getName()); } //6. get all methods in this class Method[] declaredMethods = personCls.getDeclaredMethods(); for (Method method :declaredMethods) { System.out.println(method.getName()); } //7. Get constructors of all public modifications. For this class, excluding the parent class Constructor<?>[] constructors = personCls.getConstructors(); for (Constructor constructor :constructors) { System.out.println(constructor.getName()); } //8. Get all constructors of this class Constructor<?>[] declaredConstructors = personCls.getDeclaredConstructors(); for (Constructor constructor :declaredConstructors) { System.out.println(constructor.getName()); } //9. Return Package information in the form of Package System.out.println(personCls.getPackage()); //10. Return parent Class information in the form of Class System.out.println(personCls.getSuperclass()); //11. Return interface information in the form of Class [] Class<?>[] interfaces = personCls.getInterfaces(); for (Class aClass :interfaces) { System.out.println(aClass.getName()); } //12. Return Annotation information in the form of Annotation [] Annotation[] annotations = personCls.getAnnotations(); for (Annotation annotation :annotations) { System.out.println(annotation); } } @Test public void api_02() throws ClassNotFoundException { Class<?> personCls = Class.forName("reflection.Person"); //The second group is Java lang.reflect. Field class //Get all properties in this class Field[] declaredFields = personCls.getDeclaredFields(); for (Field field :declaredFields) { //getName returns the property name //getModifiers returns modifiers as int //The default modifier is 0, public is 1, private is 2, protected is 4, static is 8 and final is 16 //getType returns the type as Class System.out.println(field.getName() + " The modifier value of the property" + field.getModifiers() +" The type of the property"+field.getType()); } //The third group is Java lang.reflect. Method class //Get all methods in this class Method[] declaredMethods = personCls.getDeclaredMethods(); for (Method method :declaredMethods) { //getName returns the property name //getModifiers returns modifiers as int //The default modifier is 0, public is 1, private is 2, protected is 4, static is 8 and final is 16 //getReturnType returns the type as Class System.out.println(method.getName() + "This method modifier" + method.getModifiers() +"The type of the method"+method.getReturnType()); //getParameterTypes gets the current method parameters in the form of Class [] Class<?>[] parameterTypes = method.getParameterTypes(); for (Class<?> parameterType : parameterTypes) { System.out.println(parameterType); } } //The fourth group is Java lang.reflect. Constructor class //getName returns the property name //getModifiers returns modifiers as int Constructor<?>[] declaredConstructors = personCls.getDeclaredConstructors(); for (Constructor constructor :declaredConstructors) { System.out.println(constructor.getName()); //getParameterTypes gets the current method parameters in the form of Class [] Class[] parameterTypes = constructor.getParameterTypes(); for (Class parameterType : parameterTypes) { System.out.println("Constructor parameters" + parameterType); } } } } class A{ public String hobby; public A() { } public void hi(){ } } interface IA{} interface IB{} @Deprecated class Person extends A implements IA ,IB{ public String name; protected int age; String job; private double sal; public Person(){ } public Person(String s){ } private Person(String s,int i){ } public void m1(String name,int age){ } protected void m2(){ } void m3(){ } private void m4(){ } }
-
Create objects by reflection
Method 1: call the public modified parameterless constructor in the class
Method 2: call the specified constructor in the class
Class related methods:
newInstance: call the parameterless constructor in the class to get the object of the corresponding class
getConstructor(Class... clazz): get the corresponding public constructor object according to the parameter list
Getdeclaredconstructor (class... clazz): get all corresponding constructor objects according to the parameter list
Constructor class related methods:
setAccessible: Blasting
newInstance(Object... obj): call constructor
/** * Create object instances through reflection mechanism */ public class ReflectionCreateInstance { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { //String classPath = "reflection.User"; //1. Get the Class object of User Class first Class<?> userClass = Class.forName("reflection.User"); //2. Create an instance through the public parameterless constructor Object o1 = userClass.newInstance(); System.out.println(o1); //3. Create an instance through the public parameterized constructor Constructor<?> constructor = userClass.getConstructor(String.class); Object o2 = constructor.newInstance("tom"); System.out.println(o2); //4. Create an instance through a non-public parameterized constructor Constructor<?> declaredConstructor = userClass.getDeclaredConstructor(int.class, String.class); declaredConstructor.setAccessible(true);//Blasting, using reflection, you can access the private constructor Object o3 = declaredConstructor.newInstance(20, "mike"); System.out.println(o3); } } class User { private int age = 10; private String name = "jack"; public User() { } public User(String name) { this.name = name; } private User(int age, String name) { this.age = age; this.name = name; } @Override public String toString() { return "User{" + "age=" + age + ", name='" + name + '\'' + '}'; } }
-
Accessing members in a class through reflection
/** * Accessing members in a class through reflection */ public class ReflectAccessProperty { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException { //1. Get the Class object corresponding to the Student Class Class<?> stuClass = Class.forName("reflection.Student"); //2. Create object Object o = stuClass.newInstance(); //3. Use reflection to get the age attribute object Field age = stuClass.getField("age"); age.set(o,88);//Through reflection operation System.out.println(o); System.out.println(age.get(o)); //4. Operation name attribute Field name = stuClass.getDeclaredField("name"); name.setAccessible(true); name.set(o,"tom"); //Or name set(null,"tom"); Because name is static System.out.println(name.get(o)); } } class Student{ public int age; private static String name; public Student() { } @Override public String toString() { return "Student{" + "age=" + age + " name=" + name+ '}'; } }
-
Accessing methods in a class through reflection
/** * Accessing methods in a class through reflection */ public class ReflectAccessMethod { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { //1. Get the Class object corresponding to the Boss Class Class<?> bossCls = Class.forName("reflection.Boss"); //2. Create object Object o = bossCls.newInstance(); //3. Call public method Method hi = bossCls.getMethod("hi", String.class); //Method hi = bossCls.getDeclaredMethod("hi",String.class); it's fine too //4. Call hi.invoke(o, "jack"); //Call private method Method say = bossCls.getDeclaredMethod("say", int.class, String.class, char.class); say.setAccessible(true); System.out.println(say.invoke(o, 5, "tom", 'A')); //Similarly, because the say method is static, o can also be changed to null //be careful!!! In reflection, if the method has a return value, it returns Object uniformly } } class Boss { public int age; private static String name; public Boss() { } private static String say(int n, String s, char c) { return n + " " + s + " " + c; } public void hi(String s) { System.out.println("hi " + s); } }