運行時類型識別(RTTI,Run-Time Type Identification)是 Java 多態、反射、動態代理等高級特性的基石。JVM 在運行期維護每個類的元數據,封裝於 java.lang.Class 對象中。
若類是對象的模板,Class 就是類的模板。每個已加載類在 JVM 中對應唯一 Class 實例。
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
Human person = new Human();
// 1. 對象.getClass() —— 最常用
Class> c1 = person.getClass();
// 2. Class.forName("全限定名") —— 動態加載,配置驅動核心
Class> c2 = Class.forName("Human");
// 3. 類字面常量 .class —— 編譯期綁定,性能最好
Class> c3 = Human.class;
System.out.println(c1.getName()); // 輸出: Human
System.out.println(c2.getSimpleName());
System.out.println(c3.getPackage().getName());
}
}

Human woman = new Woman(); // 向上轉型 Class> c = woman.getClass(); // 依然是 Woman.class // 調用 woman.breath() 時: // 1. JVM 讀取 woman 引用指向對象的 Class 對象(Woman.class) // 2. 在 Woman.class 方法表查找 breath() // 3. 執行 Woman 版本(若覆寫)或繼承自 Human 版本 // 引用類型 Human 不影響分派,Class 對象才是真相
無論引用如何向上轉型,對象頭部的 Class 指針不變,保證動態綁定正確性。
| 方法 | 用途 |
|---|---|
getName() | 全限定類名 |
getSimpleName() | 簡單類名 |
getPackage() | Package 對象 |
newInstance() | 調用無參構造創建實例(已棄用,用 Constructor.newInstance) |
getFields() | 所有 public 域(含繼承) |
getDeclaredFields() | 本類聲明的所有域(含 private) |
getMethods() | 所有 public 方法(含繼承) |
getDeclaredMethods() | 本類聲明的所有方法 |
getConstructors() | public 構造器 |
getSuperclass() | 父類 Class 對象 |
getInterfaces() | 實現的接口數組 |
isAnnotationPresent() | 註解檢查 |