JDK 6+ 編譯以下代碼時,編譯器輸出 unchecked 警告:
Class myClass = MethodPointerTest.class;
Method add = myClass.getMethod("add", int.class, int.class);
// 警告: [unchecked] 對作為普通類型 java.lang.Class 的成員的 getMethod(java.lang.String,java.lang.Class<?>...) 的調用未經檢查
Class 自 JDK 5 引入泛型:Class<T>。原始碼使用原始類型 Class(等同 Class<Object>),導致編譯器無法進行類型安全檢查,發出未經檢查調用警告。
Class<?>(最常用)Class<?> myClass = MethodPointerTest.class;
Method add = myClass.getMethod("add", int.class, int.class);
// 無警告:編譯器知道這是某種具體類型的 Class 對象
Class<MethodPointerTest>Class<MethodPointerTest> myClass = MethodPointerTest.class;
// 更精確,若後續需 newInstance() 等操作更安全
Class 類核心方法簽名(JDK 8):
public class Class<T> {
public Method getMethod(String name, Class<?>... parameterTypes) { ... }
public T newInstance() throws InstantiationException, IllegalAccessException { ... }
public <U> Class<? extends U> asSubclass(Class<U> clazz) { ... }
}
Class<?> 明確告訴編譯器:這是「某種具體類型的 Class 對象」,而非「任意類型的 Class」getMethod 參數 Class<?>... 已經是通配符,傳入 int.class(即 Class<Integer>)類型安全Method 不涉及泛型參數 T,故不影響調用鏈public class ReflectionDemo {
public static void main(String[] args) {
// 1. 正確聲明泛型 Class
Class<?> clazz = ReflectionDemo.class;
try {
// 2. 獲取公共方法(含繼承)
Method add = clazz.getMethod("add", int.class, int.class);
System.out.println("Method: " + add);
// 3. 獲取聲明方法(不含繼承,含 private)
Method declared = clazz.getDeclaredMethod("internalAdd", int.class, int.class);
declared.setAccessible(true); // 破壞封裝訪問私有方法
// 4. 調用靜態方法(實例傳 null)
Object result = add.invoke(null, 3, 5);
System.out.println("3 + 5 = " + result);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
public static int add(int a, int b) { return a + b; }
private static int internalAdd(int a, int b) { return a + b; }
}
Class,改用 Class<?> 或具體 Class<ConcreteType>-Xlint:unchecked 下零警告通過Class<T>