Loading timing such as virtual machine class loading mechanism (JVM study notes)

class declaration cycle

A class starts from being loaded into virtual machine memory and ends when it is unloaded from memory. Its life cycle includes:

Load->Verify->Prepare->Parse->Initialize->Use->Unload

When does the first stage of class loading start?

  1. When encountering the 4 bytecode instructions of new, getstatic, putstatic or invokestatic. If the class has not woken up to be initialized, its initialization is triggered first. Common scenarios: new instantiate objects, read or set a static field of a class (modified by final, except for static fields that have put the result into the constant pool during compilation), and call static methods.
  2. When using the method of the java.lang.reflect package to make a reflection call to a class, if the class has not been initialized, the initialization must be triggered first.
  3. When initializing a class, if it is found that its parent class has not been initialized, it will initialize its parent class first.
  4. When the virtual machine starts, the user needs to specify a main class to be executed, and the virtual machine initializes this main class.

    The behavior of these four scenarios becomes an active reference to a class. Except for the above methods of referencing a class, initialization will not be triggered, which is called passive reference.

Passive reference example 1:

package classloading;

public class SuperClass {
    static {
        System.out.println("classloading.SuperClass init!");
    }

    public static int value = 123;
}
package classloading;

public class SubClass extends SuperClass {
    static {
        System.out.println("subclass init!");
    }
}
package classloading;
public class NotInitialization {
    public static void main(String[] args) {
        System.out.println(SubClass.value);
    }
}

Output result:

classloading.SuperClass init!

123

For static fields, only the class that directly defines the field will be initialized, so referencing a static field defined by a parent class through a subclass will not trigger subclass initialization. Whether to trigger depends on the specific implementation of the virtual machine.

Passive reference example 2:

package classloading;
public class NotInitialization {
    public static void main(String[] args) {
        SuperClass[] sca=new SuperClass[10];
    }
}

After running, it is found that no subclass or parent class initialization is triggered.

Passive reference example 3:

package classloading;
public class ConstantClass {
    static {
        System.out.println("ConstantClass init!!");
    }
    public static final String HELLOWORLD = "hello world!";
}
package classloading;
public class NotInitialization {
    public static void main(String[] args) {
        System.out.println(ConstantClass.HELLOWORLD);
    }
}

After running, it is found that ConstantClass init is not printed out! ! , this is because the java source code stores the value of the secondary constant in the constant pool of NotInitialization during the compilation phase, and the reference to the constant ConstantClass.HELLOWORLD is actually transferred into a reference to its own constant pool.

Interface initialization:

接口与类初始化区别:类在书初始化的时候需要其父类全部初始化,但是接口在初始化时候,并不需要父接口全部完成初始化,只有真正使用到父类接口的时候才会初始化。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324646094&siteId=291194637