首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 反射機制深度解析:從 Class 類到泛型擦除驗證

     編輯:Java 綜合教學

Java 反射機制深度解析:從 Class 類到泛型擦除驗證

一、反射的核心概念

運行時動態獲取類結構(屬性、方法、構造器)並操作物件的機制。主要用途:反編譯、框架開發、註解處理、動態代理等。

二、Class 類的三種獲取方式

// 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();

四、核心 API 實戰

1. 獲取方法資訊

Method[] methods = clazz.getDeclaredMethods(); // 僅本類聲明
for (Method m : methods) {
    System.out.println(m.getReturnType().getName() + " " + m.getName() + 
        Arrays.toString(m.getParameterTypes()));
}

2. 方法調用

Method m = clazz.getMethod("print", int.class, int.class);
m.invoke(obj, 10, 20); // 等同 obj.print(10, 20)

3. 獲取欄位與構造器

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 物件
  • 注意安全管理器限制與模組化(JPMS)對反射的封裝限制
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved