運行時動態獲取類結構(屬性、方法、構造器)並操作物件的機制。主要用途:反編譯、框架開發、註解處理、動態代理等。
// 1. 類字面量
Class> c1 = Foo.class;
// 2. 實例 getClass()
Foo foo = new Foo();
Class> c2 = foo.getClass();
// 3. 全限定名載入
Class> c3 = Class.forName("com.example.Foo");
// 三者指向同一 Class 物件:c1 == c2 == c3 → true
Foo instance = (Foo) c1.newInstance(); // 需無參構造器
instance.print();
Method[] methods = clazz.getDeclaredMethods(); // 僅本類聲明
for (Method m : methods) {
System.out.println(m.getReturnType().getName() + " " + m.getName() +
Arrays.toString(m.getParameterTypes()));
}
Method m = clazz.getMethod("print", int.class, int.class);
m.invoke(obj, 10, 20); // 等同 obj.print(10, 20)
Field[] fields = clazz.getDeclaredFields();
Constructor>[] ctors = clazz.getDeclaredConstructors();
ArrayList list = new ArrayList<>();
list.add("hello");
// 編譯期阻止:list.add(20);
// 繞過編譯期檢查
Method m = list.getClass().getMethod("add", Object.class);
m.invoke(list, 20); // 成功插入 Integer
System.out.println(list); // [hello, 20]
結論:泛型僅在編譯期有效,運行期會被擦除為原始類型。
getDeclaredMethod/getDeclaredFields 獲取私有成員setAccessible(true) 並緩存 Method 物件