Class loading
Basic description: reflection mechanism is the key to Java's implementation of dynamic language, that is, class dynamic loading through reflection.
- Static loading: load relevant classes during compilation. If the relevant classes do not exist, an error will be reported, which is highly dependent.
- Dynamic loading: loads the required class at runtime. If the class is not used and does not exist, no error will be reported; If this class is used and does not exist, an error is reported. Reduced dependency.
package reflection_; import java.lang.reflect.Method; import java.util.Scanner; /** * @Author: Gin * @Description: * @Modified By: Gin * @Date: Created in 18:49 2021/9/28 */ public class ClassLoad_ { public static void main(String[] args) throws Exception { Scanner scanner = new Scanner(System.in); System.out.println("Please enter key"); int key = scanner.nextInt(); switch (key){ case 1: // When compiling, the Tiger class is loaded. If the Tiger class does not exist, an error is reported directly, // Tiger tiger = new Tiger(); // tiger.cry(); break; case 2: // No error will be reported during compilation // During operation, an error will be reported only when 2 is entered Class cls = Class.forName("Person"); Object o = cls.newInstance(); Method method = cls.getMethod("work"); method.invoke(o); break; default: System.out.println("do nothing..."); } } }
Class loading timing
- When creating an object (new) / / load statically
- When a child class is loaded, the parent class will also be loaded / / statically loaded
- When calling static members in a class / / load statically
- Reflection / / dynamic loading
Class loading process diagram
Supplement:
In the three stages of class loading, loading and connection are controlled by the JVM. Initialization can be manually added with Java code, and then initialized by the JVM.
Five stages of class loading
- load:
The main purpose of the JVM at this stage is to convert bytecode from different data sources (possibly Class files, jar packages, or even networks) into binary byte streams, load them into memory, and generate a java.lang.Class object representing this Class - connect:
(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 security 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 for static variables and initialize them by default (corresponding to the default initial values of data types, such as 0, 0L, null, false, etc.). The memory used by these variables will be allocated in the method area
package reflection_; /** * @Author: Gin * @Description: * @Modified By: Gin * @Date: Created in 9:12 2021/9/29 */ public class ClassLoad_01 { public static void main(String[] args) { } } class Test01{ // Properties - member variables - fields // Class load connection phase - prepare the following operations for resolution: // 1. n1 is an instance attribute, not a static variable, so memory will not be allocated in the preparation phase // 2. n2 is a static variable to allocate memory. n2 is initialized to 0 by default instead of 20 // 3. n3 static final is a constant, which is different from static variables. It is directly assigned to 30 public int n1 = 10; public static int n2 = 20; public static final int n3 = 30; }
(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 is not really 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.
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
package reflection_; /** * @Author: Gin * @Description: * @Modified By: Gin * @Date: Created in 9:34 2021/9/29 */ public class ClassLoad_02 { public static void main(String[] args) throws ClassNotFoundException { // analysis // 1. Load: load Class B and generate Class objects of Class B // 2. Connection: initialize the static variable num by default, num = 0 // 3. Initialization phase: // In this way, the assignment actions of all static variables in the class and the statements in the static code block are automatically collected and merged /* clinit(){ System.out.println("B Static code block is executed ""); num = 300; num = 100; } Merge: num = 100 */ // 4. The B () {} constructor is executed // new B(); / / class loading // B = New B (bottom layer): /* protected Class<?> loadClass(String name,boolean resolve) throws ClassNotFoundException { // Because of this mechanism, it is possible to ensure that a Class has only one Class object in memory synchronized (getClassLoadingLock(name)) { .... } } */ System.out.println(B.num); // 100. If you directly use the static properties of the class, it will also lead to the loading of the class } } class B{ static { System.out.println("B Static code blocks are executed"); num = 300; } static int num = 100; public B() { System.out.println("B() The constructor is executed"); } }