1、接口初始化規則
已知:
1、靜态常量分為編譯期常量和運作期常量
2、讀取或設定一個類型的靜态字段(非編譯期常量)的時候會進行初始化
3、調用一個類型的編譯期常量的時候不會導緻該類初始化,甚至該類都不會被加載
4、對于靜态字段,隻有直接定義了這個字段的類才會被初始化
5、接口中都是靜态常量
接口的特殊點:
1、實作該接口的子類或者子接口進行初始化的時候,不會根據那七種情況中的子類初始化會導緻父類初始化這條規則,導緻父接口的初始化。
2、隻有調用該接口的運作期常量的時候,才會導緻接口的初始化。
注:
1、删除class檔案,不能用來判斷是否進行了初始化,隻能用來判斷是否進行了加載。
2、接口作為父接口跟類作為父類的差別在于:接口是被動的,類是主動的。
對于接口,不管你是否實作我,隻有你引用我的運作期常量,我才會初始化。
對于類,隻要你實作我,則你初始化我就初始化;或者引用我的運作期常量,我就會初始化。
2、準備階段與初始化階段
引例:猜輸出
public class MyTest6 {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
System.out.println("counter1" + Singleton.counter1);
System.out.println("counter2" + Singleton.counter2);
}
}
class Singleton {
public static int counter1;
public static int counter2 = 0;
private static Singleton singleton = new Singleton();
private Singleton() {
counter1++;
counter2++;
}
public static Singleton getInstance() {
return singleton;
}
}
我的想法:在main方法裡面調用了Singleton類的靜态方法,是主動使用的一種情形,是以該類會初始化,是以counter1、counter2會有初始值0,,而靜态變量singleton會調用私有的構造方法,是以兩者都會自增,是以結果應該是1、1。
實際結果:
counter1: 1
counter2: 1
引例變體:猜輸出
public class MyTest6 {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
System.out.println("counter1: " + Singleton.counter1);
System.out.println("counter2: " + Singleton.counter2);
}
}
class Singleton {
public static int counter1;
private static Singleton singleton = new Singleton();
private Singleton() {
counter1++;
counter2++;
}
public static int counter2 = 0;
public static Singleton getInstance() {
return singleton;
}
}
我的想法:
在類加載的準備階段,會給給靜态變量指派,此時counter1、counter2應該是0,singleton應該是null。當main方法中調用靜态方法時,進行初始化。因為singleton的初始化在counter2之前,是以counter1應該是1,counter2應該是0。結果應該是1、0.
實際結果:
counter1: 1
counter2: 0
可以驗證下,在私有構造方法中輸出一下:
public class MyTest6 {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
System.out.println("counter1: " + Singleton.counter1);
System.out.println("counter2: " + Singleton.counter2);
}
}
class Singleton {
public static int counter1;
private static Singleton singleton = new Singleton();
private Singleton() {
counter1++;
counter2++;
System.out.println(counter1);
System.out.println(counter2);
}
public static int counter2 = 0;
public static Singleton getInstance() {
return singleton;
}
}
結果:
1
1
counter1: 1
counter2: 0