第2の困惑:タイプが完全に初期化されない前にインスタンスオブジェクトが表現する場合

2429 ワード

public class MainTest { 
public static void main(String[] args) { 
Singleton obj = Singleton.getInstance(); 
System.out.println("obj.counter1==" + obj.counter1); 
System.out.println("obj.counter2==" + obj.counter2); 
} 
} 

class Singleton { 

public static int counter1; 
public static int counter2 = 0; 
private static Singleton obj = new Singleton(); 
private Singleton() { 
counter1++; 
counter2++; 
} 

public static Singleton getInstance() { 
return obj; 
} 
} 

結果:
obj.counter1==1obj.counter2==1
もう一度見てください.
public class MainTest { 
public static void main(String[] args) { 
Singleton obj = Singleton.getInstance(); 
System.out.println("obj.counter1==" + obj.counter1); 
System.out.println("obj.counter2==" + obj.counter2); 
} 
} 

class Singleton { 
private static Singleton obj = new Singleton(); 
public static int counter1; 
public static int counter2 = 0; 

private Singleton() { 
counter1++; 
counter2++; 
} 

public static Singleton getInstance() { 
return obj; 
} 
} 

 
結果:
obj.counter1==1obj.counter2==0
質問:なぜ後者のcounter 2は1ではなく0なのか.
=================================================================================
参考理解:
1つ目:
main関数でSingletonの静的メソッドを呼び出すと、仮想マシンはSingletonクラスのみをロードし、静的フィールドを初期化しますが、このようなオブジェクトを作成するスペースは割り当てられません.public static int counter1; public static int counter2 = 0; private static Singleton obj = new Singleton(); 静的変数counter 1が実行され、counter 2が初期化された後、new Singleton()命令に遭遇し、仮想マシンはSingletonが初期化されているかどうかを確認し始め、完全に初期化されていないことを確認し、仮想マシンは初期化を開始し、構築方法を呼び出してインスタンスオブジェクトを生成するので、counter 1++を実行する.counter2++; 以前は、両方の値が0でcounter 1++が実行されていました.counter2++; 次は1,1です.2つ目はprivate static Singleton obj=new Singleton()です.public static int counter1; public static int counter2 = 0; 仮想マシンがnew Singleton(前述と第1種と同様)を実行する場合、まずSingletonクラスが初期化されているかどうかを確認し、初期化されていないことを発見したので、初期化を継続し、その後空間を割り当ててオブジェクトを作成し、counter 1++を実行する.counter2++; このときcounter 1もcounter 2も1ですが、private static Singleton obj=new Singleton();文が終了した後も、このようなメソッド呼び出しは続行されるため、public static int counter 1の実行が続行されます.public static int counter2 = 0; したがってcounter 2は0に再割り当てられる.