運行時類型識別(RTTI)主要有兩種形式:
每個類在編譯後生成 .class 文件,JVM 類加載時創建對應的 Class 對象,包含類的完整元數據(字段、方法、構造器、註解等)。
// 1. 編譯時已知類型
Class c1 = String.class;
// 2. 實例對象獲取
String s = "hello";
Class c2 = s.getClass();
// 3. 運行時動態加載(反射核心)
Class c3 = Class.forName("java.lang.String");
(Apple) fruit,失敗拋 ClassCastExceptionc.newInstance()(需無參構造器)instanceof / Class.isInstance() 考慮繼承關係;equals() / == 僅比較精確類型RAD 工具(如 GUI 構建器)需在運行時檢查組件的屬性、方法、事件處理器。反射提供 getFields()、getMethods()、getConstructors() 等 API,使工具能動態讀取/設置組件狀態、綁定事件。
跨網絡創建/運行對象,利用分佈式計算資源。反射使服務端能動態加載客戶端發送的類定義,實現透明的遠程對象調用。
| 類 | 用途 |
|---|---|
| Field | 表示字段,提供 get()/set() 讀寫值 |
| Method | 表示方法,提供 invoke() 動態調用 |
| Constructor | 表示構造器,提供 newInstance() 創建對象 |
所有類實現 Member 接口,由 JVM 運行時創建,代表未知類的對應成員。
多態調用有性能開銷時,可用 RTTI 針對特定類型優化(如 if (obj instanceof ConcreteType) 直接調用具體方法),但會降低代碼通用性。反射更靈活但有額外開銷,應在框架開發、動態代理、配置驅動等場景謹慎使用。
Class> clazz = Class.forName("com.example.Service");
Object service = clazz.getDeclaredConstructor().newInstance();
Method process = clazz.getMethod("process", String.class);
Object result = process.invoke(service, "input");
System.out.println(result);