執行時型別資訊
RTTI(在執行時,識別一個物件的型別)可以在程式執行時發現和使用型別資訊,這就打破了只能在編譯期執行面向型別的操作的限制。使用它,可以查詢某個Shape引用所指向的物件的確切型別,然後選擇或者剔除特例。在面向物件程式設計中,一般讓程式碼只操縱對基類的引用。在Java中,所有的型別轉換都是在執行時進行正確性檢查的。
Shape物件實際執行什麼樣的程式碼,是由引用所指向的具體物件(Circle、Square或者Triangle)而決定的。這符合要求:你希望大部分程式碼儘可能少地瞭解物件的具體型別,而是隻與物件家族中的一個通用表示打交道(Shape基類)。這樣的程式碼會容易寫、讀和維護。
Class物件
class物件負責表示在執行時的型別資訊,它包含了與類有關的資訊。每當編寫並編譯了一個新類,就會產生一個Class物件(更恰當地說,是被儲存在一個同名的.class檔案中)。Java程式在它開始執行之前並非被完全載入,其各個部分是在必需時才載入的。當程式建立第一個對類的靜態成員的引用(構造器也是類的靜態方法)時,就會載入這個類到JVM中。
類載入器首先檢查這個類的Class物件是否已經載入。如果未載入,預設的類載入器就會根據類名查詢.class檔案,而且其位元組碼被載入時,要接受驗證,以確保其沒有被破壞。一旦某個類的Class物件被載入記憶體,它就被用來建立這個類的所有物件。無論何時,只要你想在執行時使用型別資訊,就必須首先獲得對恰當的Class物件的引用,實現此功能的途徑有:
Class.forName("全限定名")會取得一個Class物件的引用,苦類還沒有被載入就載入它,找不到你要載入的類,會丟擲異常ClassNotFoundException;
如果你已經擁有了一個感興趣的型別的物件,可以通過呼叫getClass()方法來獲取Class引用,這個方法將返回表示該物件的實際型別的Class引用。Class.getName()、getSimpleName()和getCanonicalName()分別會產生全限定的類名、類別和全限定類名。當使用Class.newInstance()建立新例項時,會得到Object引用,但這個引用指向的實際物件。