一、例1
1.問題
public class Demo01_StaticTest {
private static Demo01_StaticTest st = new Demo01_StaticTest();
public static int count1;
public static int count2 = 0;
private Demo01_StaticTest(){
count1++;
count2++;
}
public static Demo01_StaticTest getInstance(){
return st;
}
public static void main(String[] args) {
Demo01_StaticTest st = Demo01_StaticTest.getInstance();
System.out.println("count1: " + st.count1);
System.out.println("count2: " + st.count2);
}
}
2.分析
- 從
main
方法中的順序開始分析
3.問題變化
public class Demo02_StaticTest {
public static int count1;
public static int count2 = 0;
private static Demo02_StaticTest st = new Demo02_StaticTest();
private Demo02_StaticTest(){
count1++;
count2++;
}
public static Demo02_StaticTest getInstance(){
return st;
}
public static void main(String[] args) {
Demo02_StaticTest st = Demo02_StaticTest.getInstance();
System.out.println("count1: " + st.count1);
System.out.println("count2: " + st.count2);
}
}
4.分析
- 完全一樣的分析方法
- 最後的值爲
1,1
二、例2:父類子類中均有靜態代碼塊
1.問題
public class Demo03_StaticTest {
public static void main(String[] args) {
new Child();//請問會輸出些什麼,以及順序
}
}
class Parent{
static String name = "hello";
static {
System.out.println("parent static block");
}
public Parent(){
System.out.println("parent constructor");
}
}
class Child extends Parent{
static String childNam = "word";
static {
System.out.println("child static block");
}
public Child(){
System.out.println("child constructor");
}
}
2.分析
- 在創建子類`new Child()的時候,會按下述的順序執行
- 首先去父類中看是否用靜態相關的東西,有就先執行
- 然後再看子類中是否用靜態相關的東西,有就執行(以上兩步可以總結爲靜態先行)
- 然後再去執行父類的構造函數
- 最後再執行子類的構造函數
- 所以最後的輸出是:
3另一個重要的問題
-
當子類定義構造方法的時候,它首先會去找父類中不帶參數的構造方法
-
所以父類中不帶參數的構造方法永遠先執行
-
如果父類沒有不帶參數的構造方法,必須顯示的調用,指定調用父類的哪一個構造方法
- 這裏有個問題,爲什麼必須要先執行父類的構造方法呢?
- 可以簡單的理解,沒有父類哪來的子類呢!