實在是服了自己,子類初始化調用父類無參構造這種初學者都應該知道的事,我給忘了。
記得當初看書的時候各種概念抄在筆記本上,再上機實踐,以為一輩子都不會忘,還是給忘了。
這件事說明了兩個問題:
1.我沒有保持專注。
2.不管記性好壞都必須要復習。
我們知道在Java中,子類初始化的時候(不管是通過有參構造還是無參構造),如果繼承有父類,都會先去調用父類
的無參構造。
這個沒有問題,但是如果在父類和子類中都有static代碼塊和普通代碼塊,他們的執行先后順序又是怎樣的呢?先來看一段代碼:
A類
1 package com.test; 2 3 /** 4 * @author zhangxingrui 5 * @create 2019-03-24 21:00 6 **/ 7 public class A { 8 9 static { 10 System.out.println("我是A的static代碼塊"); 11 } 12 13 { 14 System.out.println("我是A的普通代碼塊"); 15 } 16 17 public A(){ 18 System.out.println("我是A的構造方法"); 19 } 20 21 }
B類
1 package com.test; 2 3 /** 4 * @author zhangxingrui 5 * @create 2019-03-24 21:01 6 **/ 7 public class B extends A { 8 9 static { 10 System.out.println("我是B的static代碼塊"); 11 } 12 13 { 14 System.out.println("我是B的普通代碼塊"); 15 } 16 17 public B(){ 18 System.out.println("我是B的構造方法"); 19 } 20 21 }
Main類
1 package com.test; 2 3 /** 4 * @author zhangxingrui 5 * @create 2019-03-24 21:00 6 **/ 7 public class Main { 8 9 public static void main(String[] args) { 10 B b = new B(); 11 System.out.println("---我是可愛的分割線---"); 12 B b2 = new B(); 13 } 14 15 }
好的,代碼如上,現在來看程序執行結果:
可以看到,執行順序是:
A的靜態代碼塊 》B的靜態代碼塊》A的普通代碼塊》A的構造方法》B的普通代碼塊》B的構造方法;
同時B被new了兩次,但是靜態代碼塊只執行了一次。。。
這說明了啥,說明了A不是在new的時候被執行的,而是在JVM將class文件裝載進入內存的時候就辦了(JVM將class加載到內存以后會做很多
動作,比如驗證、鏈接、解析等等)。
而普通代碼塊和構造方法都是在實例化對象的時候才被執行的。
同時也驗證了上面說的,子類在初始化的時候會調用父類的無參構造。