通常來講,在Java中,每一個類產生的編譯代碼都存在於它本身的獨立文件中,該文件只有在使用程序代碼時纔會被加載,也就是說,類的代碼只有在初次使用時才加載。可是,若是存在static的話,就不同了,當訪問static字段或static方法時,也會發生加載。最多見的static方法是構造器方法了,雖然沒有顯示寫明static關鍵字。因此,更準確地講,Java的類應該是在其任何static成員被訪問時加載的。 java
Java面向對象的三大特徵是繼承、封裝、多態。繼承的概念顧名思義,相似父子關係,子繼承父親。繼承一般被認爲是is-a關係,即子類是一個父累,能夠這樣理解。例如,大黃鴨是一個鴨子。雖然繼承是面向對象的一個重大特性,可是對於項目的架構來講,繼承應該慎用,經常使用的模式有組合,組合即一個類中持有另一個類的對象,例如咱們要構造一個汽車時,總要持有發動機、門、窗戶、輪子等這些類的具體對象,顯然汽車不是一個發動機,也不是一個輪子,它們的關係是has-a的關係,所以須要使用組合模式來設計。在OOP中,使用繼承的一個優勢是它能夠向上轉型(upcasting),即子類能夠持有父類的方法,或者說子類是一個父類,經過向上轉型,進而引出了多態的優勢,即當有方法被覆蓋時,父類類型的子類對象能夠從子類依次向上查找,知道遇到該方法即可調用,這一優勢爲程序的可擴展性奠基了基礎,如要新建一個子類,只用從新覆蓋父類中已有的某個方法便可,在調用時便可實現多態的特性。然而,繼承的使用場合應該儘可能謹慎,使用前應該問問本身是否須要向上轉型,若是後續業務中,必需要進行向上轉型,那麼就使用繼承;不然,大可沒必要使用繼承。 設計模式
那麼,在繼承這種設計模式中,程序的加載過程是怎麼進行的呢?父類的構造方法會不會加載?若是有static字段或方法,又是如何加載呢? 架構
下面,咱們以一個繼承關係的兩個類來探討該問題,類中包含有static字段。 函數
首先,寫出基類的代碼: spa
package demo0812.demo1; public class SupClass { private int i=9; protected int j; public SupClass() { System.out.println("i="+i+",j="+j); j=39; } private static int x1=printInit("SupClass.x1 initialized"); protected static int printInit(String str) { System.out.println(str); return 47; } }寫出子類的代碼:
package demo0812.demo1; public class SubClass extends SupClass { private int k=printInit("SubClass.k initialized"); public SubClass() { System.out.println("k="+k); System.out.println("j="+j); } private static int x2=printInit("SubClass.x2 initialized"); public static void main(String[] args) { System.out.println("SubClass constructor"); SubClass subClass = new SubClass(); } }從上面的兩個類代碼能夠看出,基類中含有一個static方法和一個static字段,另外還包含一個顯示的構造方法。那麼在程序執行過程當中,固然先訪問SubClass.main()方法,這是程序的入口,因而加載器開始啓動並找出SubClass的編譯代碼(SubClass.class文件),而後,注意到該類有個關鍵字extends,說明它有個父類,因而,加載器便去加載父類的代碼,即SupClass.class文件。加載器發現父類中含有一個靜態字段,因而加載器先加載這個靜態字段,同時也加載了靜態方法,因而輸出
SupClass.x1 initialized,同時將x1的值賦爲47。在加載完父類的靜態區域之後,開始加載子類的靜態區域,加載器因而看到,在子類中,也有一個靜態字段x2,而且對它進行初始化,因而輸出
SubClass.x2 initialized,同時,將x2的值賦爲47。這時,父類和子類的靜態區都已經加載完成,因而,接着讀取main函數,首先輸出main中的第一行命令
SubClass constructor接着,執行第二行命令,即對子類進行實例化,注意對子類實例化以前必定會對父類進行實例化,因而輸出
i=9,j=0接着,對子類進行按序執行,首先輸出
SubClass.k initialized
並對k賦值爲47,最後輸出 設計
k=47 j=39