反射是 Java 動態性的基石,允許運行時檢查類、接口、字段和方法的信息。getClass() 是進入反射世界的鑰匙,本文深度解析 Class 對象的獲取方式、類型信息提取及實際應用場景。
String str = "Hello"; Class<?> clazz = str.getClass(); // 返回 String.class
Class<String> clazz = String.class; Class<int> intClass = int.class; // 基本類型也有 Class 對象 Class<String[]> arrClass = String[].class; // 數組類型
Class<?> clazz = Class.forName("java.lang.String");
// 拋出 ClassNotFoundException,需捕獲
區別:前兩種在編譯期確定類型,第三種支持運行時動態決定,是框架開發的核心。
Class<?> clazz = String.class; clazz.getName(); // 全限定名 "java.lang.String" clazz.getSimpleName(); // 簡單名 "String" clazz.getPackage(); // Package 對象 clazz.getModifiers(); // 修飾符 (public, final 等)
clazz.getSuperclass(); // 父類 Class clazz.getInterfaces(); // 實現的接口數組 clazz.getGenericSuperclass(); // 帶泛型的父類 clazz.getGenericInterfaces(); // 帶泛型的接口
// 字段
clazz.getDeclaredFields(); // 所有聲明字段(含私有)
clazz.getFields(); // 所有公共字段(含繼承)
clazz.getDeclaredField("name"); // 獲取特定字段
// 方法
clazz.getDeclaredMethods(); // 所有聲明方法
clazz.getMethods(); // 所有公共方法(含繼承)
clazz.getDeclaredMethod("methodName", paramTypes);
// 構造器
clazz.getDeclaredConstructors();
clazz.getConstructor(paramTypes);
clazz.isPrimitive(); // 基本類型 clazz.isArray(); // 數組 clazz.isInterface(); // 接口 clazz.isEnum(); // 枚舉 clazz.isAnnotation(); // 註解 clazz.isAnonymousClass(); // 匿名類 clazz.isMemberClass(); // 內部類 clazz.isLocalClass(); // 局部類
Class<? extends Number> numClazz = clazz.asSubclass(Number.class); // 編譯期檢查是否為 Number 子類
// 無參構造器
Object obj = clazz.getDeclaredConstructor().newInstance();
// 帶參構造器
Constructor<?> ctor = clazz.getConstructor(String.class, int.class);
Object obj = ctor.newInstance("param", 123);
if (clazz.isAnnotationPresent(Table.class)) {
Table table = clazz.getAnnotation(Table.class);
String tableName = table.value();
}
public <T> T createInstance(Class<T> clazz) {
Constructor<T> ctor = findInjectableConstructor(clazz);
Object[] args = resolveDependencies(ctor.getParameterTypes());
return ctor.newInstance(args);
}
Class<?>[] interfaces = clazz.getInterfaces(); Proxy.newProxyInstance(clazz.getClassLoader(), interfaces, handler);
Class.forName() 較重,建議緩存--add-opens 導出包Class 對象是 JVM 中類型信息的運行時表達,getClass()、.class、Class.forName() 三條獲取路徑各有適用場景。掌握反射 API,是理解 Spring、Hibernate、MyBatis 等主流框架原理的前提,也是構建動態化、可擴展系統的關鍵技能。