Case Analysis of Java's Class Loading Mechanism

1. What is the class loading mechanism of java

1. Concept

Personally understand that the so-called java class loading is the process of loading the compiled class file into the jvm to become a class object that can be referenced.

2. Process

write picture description here
Loading (loading): Find and import Class files
Verification : Check the correctness of the loaded Class file data to see if there is any dangerous data that will kill the jvm
Preparation: The stage of allocating memory for class variables and setting class variable initial values ​​()

At this time, memory allocation only includes class variables (variables modified by static), not instance variables. Instance variables will be allocated in the Java heap along with the object when the object is instantiated; the initial value mentioned here" Usually "the case" is the zero value of the data type, if:
static int value = 100;
the initial value of value after the preparation phase is 0 instead of 100, and the putstatic instruction that assigns value to value will be executed during the initialization phase.

Parsing: The parsing phase is the process by which the virtual machine replaces symbolic references in the constant pool with direct references. The parsing action is mainly for class or interface, field, class method, interface method, method type, method handle and call point qualifier 7 types of symbol references
Initialization : Perform initialization operations on static variables and static code blocks of the class, that is, execute the class The process of the constructor() method:

The () method is generated by the compiler automatically collects the assignment action of all class variables in the class and the statement in the static statement block static{}. The order collected by the compiler is determined by the order in which the statements appear in the source file. , the static statement block can only access the variables defined before the static statement block, and the variables defined after it can be assigned values ​​in the preceding static statement block, but cannot be accessed

This is the end of the text part, I don’t want to type any more. To be honest, I don’t like reading long texts. Compared with writing code, I prefer to practice and understand. Therefore, I will use a case to briefly talk about it. own understanding.

2. Case analysis

1. Classic case

Case number one

package jvmload;
public class StaticTest {
    public static void main(String[] args) {
        staticFunction();
    }

    static StaticTest st = new StaticTest();//注意这点

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

    {
        System.out.println("2");
    }

    StaticTest() {
        System.out.println("3");
        System.out.println("a=" + a + ",b=" + b);
    }

    public static void staticFunction() {
        System.out.println("4");
    }

    int a = 110;
    static int b = 112;
}

This code. Whether you have seen it or not, I will pretend that everyone has not seen it.
Running result:

2
3
a=110,b=0
1
4

If it is the first time to see this case, you will feel very strange. Why is the output like this? Why is 2 printed first, why a has a value, and b=0? No hurry, let’s look at a piece of code first :
Case 2

package jvmload;
public class StaticTest1 {
    public static void main(String[] args) {
        staticFunction();
    }
    static {
        System.out.println("1");
    }

    {
        System.out.println("2");
    }

    StaticTest1() {
        System.out.println("3");
        System.out.println("a=" + a + ",b=" + b);
    }

    public static void staticFunction() {
        System.out.println("4");
    }

    int a = 110;
    static int b = 112; 
    static StaticTest1 st = new StaticTest1();//注意这点
}

Guess what is the running result of this code? The
running result:

1
2
3
a=110,b=112
4

I believe everyone has already seen that the difference between the second code and the first code is actually the location of static StaticTest1 st = new StaticTest1() is different.
At this time, you may have doubts, why only one line of code was moved The location and the running results are very different? Now
, please listen to me explain slowly: I only explain Case 1, and everyone in Case 2 understands it by themselves.
As I said at the beginning of this chapter, the loading process is: Load -> Connection (Verification, Preparation, Analysis) -> Initialization.
1. In the preparation phase, the default value will be set for the class variable, so in case 1: st=null, b=0 ,
2. In the initialization phase, the class construction will be executed first device,

A class constructor is a compiler that collects all static statement blocks and assignment statements of class variables and merges the statements in the order of the source code to generate a class constructor. The construction method of an object is (), and the construction method of a class is ().

In other words, it is to execute static modified code blocks and assign values ​​to static modified variables. The execution order of static modified code blocks and class variables is executed according to the order in which they are in the file. And static StaticTest st = new StaticTest() is ranked first, so new StaticTest() will be executed , that is, the initialization of
the object 2.1. During the initialization process of the object, the member variable (code block) will be executed first, and then the constructor will be executed. The execution order is also who declares first, who executes first, so the first code block

{
System.out.println("2");
}
will be executed first, so it will print 2 first . Then, execute
int a = 110;

2.2 After the member variable is executed, execute the constructor. At this time, a=110, b=0;

StaticTest() {
System.out.println(“3”);
System.out.println(“a=” + a + “,b=” + b); }

Therefore, the console will then print out 3, a=110, b=0
3. After the execution of new StaticTest(), continue to execute

static {
System.out.println("1");
}
So, next the console will print 1.
4., and finally, reach the position of b

static int b = 112;

Only at this time will b be assigned a value. Therefore, in case 2, st is placed below static int b=123, and b=123 in the result of operation, which is the reason.
If you don’t believe it, take a look below Case:
Case Three

package jvmload;
public class StaticTest {
    public static void main(String[] args) {
        staticFunction();
    }

    static StaticTest st = new StaticTest();

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

    {
        System.out.println("2");
    }

    StaticTest() {
        System.out.println("3");
        System.out.println("a=" + a + ",b=" + b);
    }

    public static void staticFunction() {
        System.out.println("4");
        System.out.println( "第二个b=" + b);//注意点
    }

    int a = 110;
    static int b = 112;
}

The difference between case three and case one: I just print b in the staticFunction() method, let's take a look at the result

2
a=110,b=0 //b in the construction method
1
4
The second b=112 //b in the staticFunction() method

One after the other, the same b., but the value is different.
5. After the initialization, the main method starts, and then the staticFunction() method is called, so the console finally outputs 4. Therefore ,
the running result of case 1 will be :

2
3
a=110,b=0
1
4

If you are not satisfied with my explanation or do not understand it, you can practice it yourself and debug it with debug.

Off topic: static code blocks vs static methods

Static code block: Some code must be executed when the project is started, this code is actively executed (when the class is loaded, the static code block is executed, and only executed once, static blocks are often used to execute class attributes. Initialization)
Static method: It needs to be initialized when the project is started. In the case of no object creation, this code is executed passively (the static method is already loaded when the class is loaded and can be called directly with the class name).

The difference between the two is:
static code blocks are executed automatically, and
static methods are executed when they are called.

Guess you like

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