catalogue
Use reflection to get Class object
Extension: parental delegation mechanism
Get properties of reflection class (file, method, constructor)
Create dynamic objects with reflections
What is reflection?
Use reflection to get Class object
public class Test { public static void main(String[] args) throws ClassNotFoundException { //Use reflection to get class objects Class c1= Class.forName("com.wjc.User"); Class c2= Class.forName("com.wjc.User"); Class c3= Class.forName("com.wjc.User"); //A Class has only one Class object in memory //After a Class is loaded, the whole structure of the Class will be encapsulated in the Class object System.out.println(c1.hashCode()); System.out.println(c2.hashCode()); System.out.println(c3.hashCode()); } }
Class class
The information that can be obtained after the object looks in the mirror: the properties, methods and constructors of a Class, and which interfaces a Class implements. For each Class, the JRE keeps an object of the same Class type for it. A Class object contains information about a specific structure (Class / interfaceenum / annotation / primitive type / void /).
Class itself is also a class
Class object can only be created by the system. We can only get this object through reflection
A loaded Class will only have one Class instance in the JVM
A class object corresponds to one loaded into the JVM Class file
Each Class instance will remember which Class instance it was generated from
All loaded structures in a Class can be completely obtained through Class
Class is the root of Reflection. For any class you want to dynamically load and run, you have to obtain the corresponding class object first
Common methods of Class
How to get Class
public class Test { public static void main(String[] args) throws ClassNotFoundException { //A Class has only one Class object in memory //After a Class is loaded, the whole structure of the Class will be encapsulated in the Class object //Method 1: get Class through object User user=new UserImpl(); Class c1 = user.getClass(); System.out.println(c1.hashCode()); //1554874502 //Method 2: use reflection to obtain class objects Class c2= Class.forName("com.wjc.UserImpl"); System.out.println(c2.hashCode()); //1554874502 //Method 3: get class by class name Class c3 = UserImpl.class; System.out.println(c3.hashCode()); //1554874502 //The eight basic types of wrapper classes have Type methods Class<Integer> type = Integer.TYPE; Class<Double> type1 = Double.TYPE; System.out.println(type); //int System.out.println(type1); //double //Gets the parent class of the class Class superclass = c1.getSuperclass(); System.out.println(superclass); //class com.wjc.User //A Class has only one Class object in memory //After a Class is loaded, the whole structure of the Class will be encapsulated in the Class object } }
public class Test02 { public static void main(String[] args) { Class c1 = Object.class; //class Class c2 = Comparable.class; //Interface Class c3 = String[].class; //array Class c4 = int[][].class; //Two dimensional array Class c5 = Override.class; //annotation Class c6 = Integer.class; //Packaging Class c7= ElementType.class; //Enumeration class Class c8=void.class; //void Class c9=Class.class; //Class itself is also a class System.out.println(c1); System.out.println(c2); System.out.println(c3); System.out.println(c4); System.out.println(c5); System.out.println(c6); System.out.println(c7); System.out.println(c8); System.out.println(c9); //As long as the element type is the same as the dimension, it is the same Class int a[]=new int[10]; int b[]=new int[100]; System.out.println(a.getClass().hashCode()); //1554874502 System.out.println(b.getClass().hashCode()); //1554874502 } }
Class loading and ClassLoader
When initializing a subclass, if it is found that its parent class has not been initialized, it is necessary to trigger the initialization of its parent class first
When creating an instance of a class (for example: new keyword, through reflection, cloning, deserialization)
When the calling class is a static method (that is, when the bytecode invokestatic instruction is used)
When using static fields of classes and interfaces (special consideration for final modification) (for example, getstatic or putstatic instructions)
If an interface defines a default method, the class that directly or indirectly implements the interface should be initialized before it
When the MethodHandle instance is initially called, initialize the class () of the method pointed to by the MethodHandle
. class will not initialize why Class does not cause class initialization - CSDN Forum
public class Test03 { static { System.out.println("Main Be loaded"); } public static void main(String[] args) throws Exception{ int m = Son.m; //Subclasses and superclasses are initialized int m1 = Son.M; //Neither the subclass nor the parent class is initialized, and M is a constant int m2=Son.b; //The parent class is initialized, but the child class is not initialized. The child class references the static variable of the parent class, which will not lead to the initialization of the child class //1. Active quotation Son son=new Son(); //Reflection also produces active references Class.forName("com.wjc.Son"); Class sonClass = Son.class; //Can't initialize the class. Why? Son.class.newInstance(); //Class is initialized. Why? } } class Father{ static int b=2; static { System.out.println("Parent class loaded"); } } class Son extends Father{ static { System.out.println("Subclass loaded"); } static int m=100; static final int M=1; }
. class will not initialize why Class does not cause class initialization - CSDN Forum
Class loader
public class Test04 { public static void main(String[] args) throws Exception{ //Gets the loader of the system class ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); System.out.println(systemClassLoader); //sun.misc.Launcher$AppClassLoader@18b4aac2 //Get the parent class loader -- > extension class loader of the system class loader ClassLoader parent = systemClassLoader.getParent(); System.out.println(parent); //sun.misc.Launcher$ExtClassLoader@5cad8086 //Get the parent class loader -- > root loader of the extension class loader (c/c + +) //java can't get it. null is printed out ClassLoader parent1 = parent.getParent(); System.out.println(parent1); //null //Test which loader the current class is ClassLoader loader = Class.forName("com.wjc.UserImpl").getClassLoader(); System.out.println(loader); //System class loader, printed as sun misc. Launcher$ AppClassLoader@18b4aac2 ClassLoader loader2 = Class.forName("java.lang.Object").getClassLoader(); System.out.println(loader2); //The root is loaded and unloaded, and the print is null //Print the path that the classloader can load System.out.println(System.getProperty("java.class.path")); /* C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\charsets.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\access-bridge-64.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\cldrdata.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\dnsns.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\jaccess.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\jfxrt.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\localedata.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\nashorn.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\sunec.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\sunjce_provider.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\sunmscapi.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\sunpkcs11.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\zipfs.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\jce.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\jfr.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\jfxswt.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\jsse.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\management-agent.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\resources.jar; C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\rt.jar; D:\Javaproject\spring-study\ReflectionDemo\target\classes; D:\apache-maven-3.8.1\repository\org\springframework\spring-webmvc\5.3.15\spring-webmvc-5.3.15.jar; D:\apache-maven-3.8.1\repository\org\springframework\spring-aop\5.3.15\spring-aop-5.3.15.jar; D:\apache-maven-3.8.1\repository\org\springframework\spring-beans\5.3.15\spring-beans-5.3.15.jar; D:\apache-maven-3.8.1\repository\org\springframework\spring-context\5.3.15\spring-context-5.3.15.jar; D:\apache-maven-3.8.1\repository\org\springframework\spring-core\5.3.15\spring-core-5.3.15.jar; D:\apache-maven-3.8.1\repository\org\springframework\spring-jcl\5.3.15\spring-jcl-5.3.15.jar; D:\apache-maven-3.8.1\repository\org\springframework\spring-expression\5.3.15\spring-expression-5.3.15.jar; D:\apache-maven-3.8.1\repository\org\springframework\spring-web\5.3.15\spring-web-5.3.15.jar; D:\IntelliJ IDEA 2021.1.3\lib\idea_rt.jar */ } }
Extension: parental delegation mechanism
The parent delegation mechanism probably looks up the package after creating the object, but it can't find its own. If you write a String class, it will not take effect. The parent delegation mechanism ensures that the core class is not destroyed
Get properties of reflection class (file, method, constructor)
//Use reflection to get class information public class Test05 { public static void main(String[] args) throws Exception{ Class c1 = Class.forName("com.wjc.User"); //Get the name of the class System.out.println(c1.getName()); //Package name + class name com wjc. User System.out.println(c1.getSimpleName()); //Class name User //Get the properties of the class Field[] fields = c1.getFields(); //Only public decorated fields can be found for (Field field : fields) { System.out.println(field); } Field[] declaredFields = c1.getDeclaredFields(); //Find all fields for (Field declaredField : declaredFields) { System.out.println(declaredField); } c1.getField("name"); //Gets the specified public decorated field c1.getDeclaredField("name");// Get the field with the specified name, unlimited System.out.println("================================="); c1.getMethods(); //Find the method of public modification c1.getDeclaredMethods(); //Find all the ways c1.getMethod("getName",null); //The method to get the specified public modification must be given the type of its parameter, otherwise it cannot be recognized, and overload should be considered c1.getMethod("setName",String.class); //Gets the method of the specified public modifier System.out.println("================================="); c1.getConstructor(); //Get public modified constructor c1.getDeclaredConstructor(); //Get all constructors c1.getDeclaredConstructor(String.class, String.class); //Gets the specified constructor } }
Create dynamic objects with reflections