instanceof、Class 字面量 (MyClass.class) 識別。Class.forName() 載入 .class 文件,動態發現並操作類的結構(欄位、方法、構造器)。// 獲取 Class 對象的三種方式
Class> c1 = MyClass.class; // 不觸發初始化
Class> c2 = obj.getClass(); // 運行時類型
Class> c3 = Class.forName("pkg.MyClass"); // 觸發初始化(靜態塊、靜態欄位)
類加載三階段:載入 (尋找 .class → 生成 Class 對象) → 鏈接 (驗證、準備靜態欄位) → 初始化 (執行靜態初始化器、靜態塊)。
| 類別 | 代表 | 常用操作 |
|---|---|---|
| Class | 類/介面/陣列/基本型別/void | getFields/getMethods/getConstructors/getDeclaredFields/forName/newInstance |
| Field | 成員變數 | get/set、setAccessible(true) 訪問 private |
| Method | 成員方法 | invoke(obj, args)、getParameterTypes、getReturnType |
| Constructor | 構造器 | newInstance(args)、getParameterTypes |
public static void copyProperties(Object src, Object dest) throws Exception {
Class> clazz = src.getClass();
for (Field f : clazz.getDeclaredFields()) {
f.setAccessible(true);
String name = f.getName();
PropertyDescriptor pd = new PropertyDescriptor(name, clazz);
Method getter = pd.getReadMethod();
Method setter = pd.getWriteMethod();
if (getter != null && setter != null) {
Object value = getter.invoke(src);
setter.invoke(dest, value);
}
}
}
InvocationHandler:攔截所有代理方法調用,統一分派邏輯。Proxy.newProxyInstance(classLoader, interfaces, handler):生成實現指定介面的代理類實例。interface Service { void doWork(String msg); }
class RealService implements Service {
public void doWork(String msg) { System.out.println("Real: " + msg); }
}
class LoggingHandler implements InvocationHandler {
private final Object target;
public LoggingHandler(Object target) { this.target = target; }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("[LOG] before " + method.getName());
Object result = method.invoke(target, args);
System.out.println("[LOG] after " + method.getName());
return result;
}
}
public class ProxyDemo {
public static void main(String[] args) {
Service real = new RealService();
Service proxy = (Service) Proxy.newProxyInstance(
Service.class.getClassLoader(),
new Class[]{Service.class},
new LoggingHandler(real));
proxy.doWork("Hello"); // 輸出 LOG → Real → LOG
}
}
RTTI:編譯器開啟並檢查
.class文件。
反射:運行時開啟並檢查.class文件。
MethodHandle / VarHandle 或緩存 Method/Field 對象優化。setAccessible(true) 破壞封裝,需謹慎使用;模組化 (JPMS) 可能限制深度反射。反射賦予 Java「運行時自我認知與操作」的能力,是框架開發的基石。掌握 Class 載用機制、核心 API、動態代理模式,並理解其效能代價與安全邊界,是進階 Java 工程師的必修課。