一道很坑的面試題,但是對理解JVM很有幫助???
解決問題
例一:
package com.evada.de;
class Singleton{
private static Singleton singleton = new Singleton();
public static int counter1;
public static long counter2 = 0;
private Singleton(){
counter1 ++;
counter2 ++;
}
public static Singleton getInstance(){
return singleton;
}
}
/**
* Created by Ay on 2016/5/24.
*/
public class LambdaTest {
public static void main(String[] args) throws Exception{
Singleton singleton = Singleton.getInstance();
System.out.println("counter1 :" + Singleton.counter1);
System.out.println("counter2 :" + Singleton.counter2);
}
}
運行結果:
counter1 :1
counter2 :0
解釋:
從main函數開始,根據JVM對類的加載機制,Singleton.getInstance()主動使用,會觸發類的加載,首先會爲類的靜態變量賦予初始值(程序從上到下執行),
即:Singleton singleton = null,counter1 = 0,counter2 = 0.
然後會進行類的初始化,即singleton = new Singleton(),會觸發構造函數,執行:
counter1 ++;
counter2 ++;
後
counter1 = 1,
counter2 = 1
最後,類在初始化後,爲類的靜態變量賦予正確的初始值,爲用戶賦予的正確值(從上到下)
即:
public static int counter1;//無用戶賦值
public static long counter2 = 0;//用戶賦予初始值0
最終結果:
counter1 :1
counter2 :0
例二:
package com.evada.de;
class Singleton{
public static int counter1;
public static long counter2 = 0;
private static Singleton singleton = new Singleton();
private Singleton(){
counter1 ++;
counter2 ++;
}
public static Singleton getInstance(){
return singleton;
}
}
/**
* Created by Ay on 2016/5/24.
*/
public class LambdaTest {
public static void main(String[] args) throws Exception{
Singleton singleton = Singleton.getInstance();
System.out.println("counter1 :" + Singleton.counter1);
System.out.println("counter2 :" + Singleton.counter2);
}
}
運行結果
counter1 :1
counter2 :1
解釋:
從main函數開始,根據JVM對類的加載機制,Singleton.getInstance()主動使用,會觸發類的加載,首先會爲類的靜態變量賦予初始值(程序從上到下執行),
即:Singleton singleton = null,counter1 = 0,counter2 = 0.
然後會進行類的初始化,即
public static int counter1;//無用戶賦值
public static long counter2 = 0;//用戶賦予初始值0
後
counter1 = 0,
counter2 = 0
singleton = new
Singleton(),會觸發構造函數,執行:
counter1 ++;
counter2 ++;
最終結果:
counter1 :1
counter2 :1
轉載自:http://bbs.jointforce.com/topic/17882