java中類載入的分析__java那些事

來源:互聯網
上載者:User

本篇文章是看《effective java》第17條有感,在其基礎上還是有所擴充。本篇文章主要探究的是:在類繼承之後,建立子類對象,對父類構造器的調用,以及類初始化的順序(即父類域的初始化,子類域的初始化)。對於這樣的分析,別什麼理論不理論,我的解決方案就是先編個程看看,實際情況是什麼樣,要是和自己理解的不一樣,再查資料,補充自己的理論體系。所以不廢話了,看代碼。

class SuperClass{public static String superStaticField="父類===靜態域";public String superField="父類===變數";static{System.out.println(superStaticField);System.out.println("父類===靜態初始化塊");}{System.out.println(superField);System.out.println("父類===初始化塊");}public SuperClass(){System.out.println("父類構造器");}}public class SubClass extends SuperClass {public static String subStaticField="子類===靜態域";public String subField="子類===變數";static{System.out.println(subStaticField);System.out.println("子類===靜態初始化塊");}{System.out.println(subField);System.out.println("子類===初始化塊");}public SubClass(){System.out.println("子類構造器");}public static void main(String[] args){System.out.println("----------------");new SubClass();}}

輸出的結果是:

父類===靜態域
父類===靜態初始化塊
子類===靜態域
子類===靜態初始化塊
----------------
父類===變數
父類===初始化塊
父類構造器
子類===變數
子類===初始化塊
子類構造器

從代碼到輸出結果我們可以看到一清二楚,我們實現了類的繼承,那首先要先有個父類,所以java做的也對,就是先初始化父類,先將父類的.class檔案載入進來,有了父類然後再載入子類。由於靜態域是類固有的域,在沒有對象之前就已經存在,是在編譯好後就已存在的域,所以在編譯好後,父類的靜態域和子類的靜態域都已經初始化好了,所以先列印的就是靜態域。然後開始類的一般變數的初始化,當然首先是從父類開始的,這也非常理解,只有在父類的所有情況全部穩定之後,子類才能進行狀態的初始化,要不然子類就沒法用父類的東西了。

   然後我們再做個實驗,把main方法裡的所有語句都注釋掉是什麼情況,你會看到只有分割線(--------------)上面的輸出了。這也剛好證實了,類的靜態域是在編譯時間候就已經初始化存在了的,是與類共生的,即使是沒有建立對象也能夠使用。 這有相當的好處,這也是《effective java》裡講的另一條,就是靜態工廠的說法,在這裡就不展開了。

下面我們從這個例子中衍生出其他的問題,其實也是繼承出現的問題,為了突出這個問題,下面讓我把代碼簡化。

import java.util.*;;class Super{public Super(){overrideMe();}public void overrideMe(){}}public class Sub extends Super{private final Date date;Sub(){date=new Date();}  public void overrideMe(){System.out.println(date);}public static void main(String[] args){                System.out.println("------輸出:");                Sub sub=new Sub();sub.overrideMe();}}
這個輸出是什麼呐。

-------輸出:

null
Fri Mar 27 15:59:56 CST 2015

第一個輸出是null,原因就是從在載入父類構造器的時候,父類構造器調用了overrideMe()方法,此方法在子類中被覆蓋,所以在調用的時候就調動了還沒有初始化的date,當然就是null了。這個問題其實分析起來並不難,主要討論的就是我們繼承java中的工具類的時候,有沒有考慮到會出現這種情況,以及如何避免這種情況的發生。《effective java》的做法是盡量使用組合的形式來擴充我們的類。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.