The "pit" of inconsistent data brought by class loading

First observe the code below and think about what the output is

public class SinglePattern{

    private static SinglePattern instance = new SinglePattern();//在类的装载就直接实例化
    public static int a;
    public static int b = 2;

    private SinglePattern(){
        a++;
        b++;
    }
    public static SinglePattern getInstance() {
        return instance;
    }

    public static void main(String[] args) {
        SinglePattern ins = SinglePattern.getInstance();
        System.out.println("a:="+ins.a);
        System.out.println("b:="+ins.b);
    }
}

The above is a singleton pattern.

Then I don't make any changes, change the location of the line of code where the class is instantiated, and think what is the output?

public class SinglePattern{

    public static int a;
    public static int b = 2;

    private static SinglePattern instance = new SinglePattern();//在类的装载就直接实例化

    private SinglePattern(){
        a++;
        b++;
    }
    public static SinglePattern getInstance() {
        return instance;
    }

    public static void main(String[] args) {
        SinglePattern ins = SinglePattern.getInstance();
        System.out.println("a:="+ins.a);
        System.out.println("b:="+ins.b);
    }
}

Have you thought about the result? ?

The result of the first run is:
write picture description here

The result of the second run is:
write picture description here

WTF?

Just change the position of a line of code, and without other major changes, the result will be different! !

In fact, this is a problem caused by the class loading process. Learn more about the class loading process. You can refer to: https://blog.csdn.net/weijifeng_/article/details/79894742

Detailed analysis of the two codes

1. Preparation stage

instance = null;
a = 0;
b = 0;

2. Initialization phase

new SinglePattern() ; a = 1; b = 1;
public static int a;  a没有指定值,就是上一步的1
public static int b = 2; b有指定初始值,初始化阶段时,b = 2;

So this is the reason why the first execution result is a = 1, b = 2

1. Preparation stage

instance = null;
a = 0;
b = 0;

2. Initialization phase

public static int a;  a没有指定值,就是上一步的0
public static int b = 2; b有指定初始值,初始化阶段时,b = 2;  
new SinglePattern() ; a = 1; b = 3;

That's what makes the difference!
The preparation phase and initialization phase of class loading strictly perform their own work, and in the initialization phase, memory values ​​are allocated in strict accordance with the order of instructions from top to bottom

Therefore, when you understand the loading process, you should know what stage you want to take to ensure that no errors will occur when taking the value.

Guess you like

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