JAVA new an object procedure

What happens in the process of new an object?

1. Confirm whether class meta information exists. When the JVM receives the new instruction, it first checks whether the class meta information to be created exists in the metaspace. If it does not exist, use the current class loader to find the corresponding class file with ClassLoader + package name + class name as the Key in the parental delegation mode. If the file is not found, a ClassNotFoundException exception will be thrown. If it is found, the class will be loaded (load - verify - prepare - parse - initialize) and the corresponding class object will be generated. 2. Allocate object memory. First, calculate the space occupied by the object. If the instance member variable is a reference variable, only allocate the space of the reference variable, that is, 4 bytes, and then divide a block of memory in the heap for the new object. When allocating memory space, synchronous operations are required, such as CAS (Compare And Swap) failure retry, area locking and other methods to ensure the atomicity of the allocation operation. 3. Set the default value. Member variable values need to be set as default values, that is, zero values in various forms. 4. Set the object header. Set the hash code, GC information, lock information and class meta information of the new object. How this process is set up depends on the JVM implementation. 5. Execute init method. Initialize the member variable, execute the instantiated code block, call the construction method of the class, and assign the first address of the object in the heap to the reference variable.

Inherited load order

Since the static block will be executed when the class is loaded for the first time, the following example uses the static block to test the loading order of the class. The construction method will not be executed until all variables are initialized. In the loading process of a class, the construction method of the class will not be executed until the internal variables are created. During class loading, objects of static member classes will be loaded first; The objects of ordinary member classes are loaded only when they are used.

example:

package com.example.demo.test;

class Father {

    public Father() {
        System.out.println("Father init block");
    }

    {
        System.out.println("I'm Father class");
    }

    static {
        System.out.println("static Father");
    }

}

public class Son extends Father {
    public Son() {
        System.out.println("Son init block");
    }

    {
        System.out.println("I'm Son class");
    }

    static {
        System.out.println("static Son");
    }

    public static void main(String[] args) {
        new Son();
    }

}

result

static Father static Son I'm Father class Father init block I'm Son class Son init block

Compiled class

package com.example.demo.test;

class Father {
    public Father() {
        System.out.println("I'm Father class");
        System.out.println("Father init block");
    }

    static {
        System.out.println("static Father");
    }
}
package com.example.demo.test;

public class Son extends Father {
    public Son() {
        System.out.println("I'm Son class");
        System.out.println("Son init block");
    }

    public static void main(String[] args) {
        new Son();
    }

    static {
        System.out.println("static Son");
    }
}

Another example

package com.example.demo.test;

class FatherTest {
    static  SonTest sonTest = new SonTest();

    public FatherTest() {
        System.out.println("FatherTest init block");
    }

    {
        System.out.println("I'm FatherTest class");
    }

    static {
        System.out.println("static FatherTest");
    }

}

public class SonTest extends FatherTest {
    public SonTest() {
        System.out.println("SonTest init block");
    }

    {
        System.out.println("I'm SonTest class");
    }

    static {
        System.out.println("static SonTest");
    }

    public static void main(String[] args) {
        new SonTest();
    }

}

result

I'm FatherTest class FatherTest init block I'm SonTest class SonTest init block static FatherTest static SonTest I'm FatherTest class FatherTest init block I'm SonTest class SonTest init block

Compiled code

package com.example.demo.test;

class FatherTest {
    static SonTest sonTest = new SonTest();

    public FatherTest() {
        System.out.println("I'm FatherTest class");
        System.out.println("FatherTest init block");
    }

    static {
        System.out.println("static FatherTest");
    }
}
package com.example.demo.test;

public class SonTest extends FatherTest {
    public SonTest() {
        System.out.println("I'm SonTest class");
        System.out.println("SonTest init block");
    }

    public static void main(String[] args) {
        new SonTest();
    }

    static {
        System.out.println("static SonTest");
    }
}

static SonTest sonTest = new SonTest(); And static {system. Out. Println ("static fathertest");} At the same level, because Sontest Sontest is in front, the line construction method is implemented first.

Added by slands10 on Sun, 27 Feb 2022 06:49:06 +0200