Java零碎知識

  1. 裝載、連接、初始化

    Java的class文件,會在裝載的時候,生成Class信息。缺失的符號,通過連接,變成直接引用。雖然我們都是對一個不存在的類發起引用的時候,發生類沒有定義的異常,但是這並不意味着裝載和連接一定是lazy模式的,只是標準規定了拋出異常的時機必須同lazy模式的時刻相同。

    初始化總是lazy的。


2. 類的私有方法

    類調用自己的私有方法,使用的是invokespecial,而不是invokevirtual。這意味着,調用私有方法不會查詢對象的函數表,而只是使用調用者所在類的方法。這和Java的語法是一致的,私有方法不重載。


3. 構造方法

    調用類的構造方法,使用的是invokespecial <init>。特殊的,會檢查第一句是不是super,如果是的話,先調用指定的父類的構造方法;如果是this,會調用其他構造方法;如果都不是,先調用無參的父類構造方法。

    Java會總是給沒有顯示聲明構造方法的類,加一個默認的無參構造方法,這點和C++很不同。

    另一個不同是,構造方法裏面調用公有方法,會查詢函數符號表,選擇重載後的函數調用。也就意味着,使用的是invokevirtual。這點和C++也不一樣,C++即使聲明瞭virtual關鍵字,由於構造的時候虛表沒有建立起來,還是調用這個父類的方法。


4. 操作數和返回值

    Java是把操作數都存放在棧中,然後根據操作符需要多少個操作數,從棧裏面取數進行運算。而不是使用寄存器,主要是出於跨平臺的考慮。

    返回值是存放在臨時變量中,這點很特殊。這意味着,如果在finally代碼塊指定了不同於try塊和catch塊指定的返回值,那麼最終的返回值應該是finally代碼塊所指定的。


5. 類加載器

   正確的類加載器的實現,應該是優先從父加載器蹭蹭遞歸查找。但是程序員重載的類加載器可以不選擇這樣做,雖然大部分都應該遵循此規則。


6. 對象與接口的函數引用

   用類引用一個對象調用方法,和用接口引用一個對象調用方法,理論上開銷是不同的,前者小一些。因爲用類引用,函數表總是能夠定下來的。總是可以直接把偏移替換掉函數名,即連接時查找。而接口則不同,需要用函數名匹配函數表,找到對應的偏移,進而得到函數代碼段的地址,即運行時查找。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章