標籤:java 基礎 標準
裝載、串連、初始化
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. 對象與介面的函數引用
用類引用一個對象調用方法,和用介面引用一個對象調用方法,理論上開銷是不同的,前者小一些。因為用類引用,函數表總是能夠定下來的。總是可以直接把位移替換掉函數名,即串連時尋找。而介面則不同,需要用函數名匹配函數表,找到對應的位移,進而得到函數程式碼片段的地址,即運行時尋找。
本文出自 “新青年” 部落格,請務必保留此出處http://luckybins.blog.51cto.com/786164/1618446
Java零碎知識