Class類的詳細說明
Class
類是Java反射機制的核心,每個Java類或接口在JVM中都有一個對應的 Class
對象,用于表示該類的元數據(如類名、方法、字段、構造器等)。以下是其核心知識點:
1. 獲取Class對象的三種方式
方式 示例 適用場景 類名.class Class<String> clazz = String.class;
已知具體類名,編譯時確定。 對象.getClass() String s = "hello"; Class<?> clazz = s.getClass();
通過已有對象獲取類信息。 Class.forName() Class<?> clazz = Class.forName("java.lang.String");
動態加載類,需全限定類名(全限定類名是帶有包名的)。
2. Class類的核心方法
(1) 獲取類的基本信息
方法 作用 String getName()
返回全限定類名(如 java.lang.String
)。 String getSimpleName()
返回簡單類名(如 String
)。 Package getPackage()
返回類所在的包信息(包名、注解等)。 int getModifiers()
返回類的修飾符(如 public
、final
),需配合 Modifier
類解析。 boolean isInterface()
判斷是否為接口。
(2) 獲取繼承關系
方法 作用 Class<?> getSuperclass()
返回直接父類的 Class
對象(若為 Object
則返回 null
)。 Class<?>[] getInterfaces()
返回類實現的所有接口的 Class
數組。
(3) 操作字段(Field)
方法 作用 Field getField(String name)
獲取指定名稱的公共字段 (包括繼承的)。 Field getDeclaredField(String name)
獲取類聲明的字段(包括私有、受保護),不包含繼承字段 。 Field[] getFields()
獲取所有公共字段(包括繼承的)。 Field[] getDeclaredFields()
獲取類聲明的所有字段(包括私有、受保護)。
(4) 操作方法(Method)
方法 作用 Method getMethod(String name, Class<?>... parameterTypes)
獲取指定名稱和參數的公共方法 (包括繼承的)。 Method getDeclaredMethod(String name, Class<?>... parameterTypes)
獲取類聲明的指定方法(包括私有、受保護),不包含繼承方法 。 Method[] getMethods()
獲取所有公共方法(包括繼承的)。 Method[] getDeclaredMethods()
獲取類聲明的所有方法(包括私有、受保護)。
(5) 操作構造器(Constructor)
方法 作用 Constructor<?>[] getConstructors()
獲取所有公共構造方法。 Constructor<?>[] getDeclaredConstructors()
獲取所有聲明的構造方法(包括私有)。 Constructor<T> getConstructor(Class<?>... parameterTypes)
獲取指定參數類型的公共構造方法。 Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
獲取指定參數類型的聲明構造方法(包括私有)。
(6) 實例化對象
方法 作用 T newInstance()
已過時 :通過默認無參構造器創建實例(需存在無參構造方法)。替代方案 :通過 Constructor
對象示例: ```java Constructor constructor = User.class.getConstructor(String.class); User user = constructor.newInstance(“Alice”); ```
(7) 其他實用方法
方法 作用 Annotation[] getAnnotations()
獲取類上的所有注解(包括元注解)。 ClassLoader getClassLoader()
返回類的類加載器。 boolean isArray()
判斷是否為數組類型。 Class<?> getComponentType()
返回數組類型的元素類型(如 String[].class.getComponentType()
→ String.class
)。
3. 示例代碼
(1) 獲取類信息
Class < ? > clazz = Class . forName ( "java.util.ArrayList" ) ;
System . out. println ( "類名: " + clazz. getName ( ) ) ;
System . out. println ( "簡單類名: " + clazz. getSimpleName ( ) ) ;
System . out. println ( "包名: " + clazz. getPackage ( ) . getName ( ) ) ;
(2) 操作私有字段
public class User { private String name; public User ( String name) { this . name = name; }
} Class < User > clazz = User . class ;
User user = clazz. getConstructor ( String . class ) . newInstance ( "Alice" ) ; Field nameField = clazz. getDeclaredField ( "name" ) ;
nameField. setAccessible ( true ) ;
nameField. set ( user, "Bob" ) ;
System . out. println ( nameField. get ( user) ) ;
(3) 調用私有方法
public class Calculator { private int add ( int a, int b) { return a + b; }
} Class < Calculator > clazz = Calculator . class ;
Calculator calc = clazz. newInstance ( ) ; Method addMethod = clazz. getDeclaredMethod ( "add" , int . class , int . class ) ;
addMethod. setAccessible ( true ) ;
int result = ( int ) addMethod. invoke ( calc, 3 , 5 ) ;
System . out. println ( result) ;
4. 注意事項
性能開銷 :反射操作比直接調用慢約10倍,避免高頻使用。安全限制 :私有成員訪問需調用 setAccessible(true)
,可能觸發安全管理器異常。代碼可讀性 :反射代碼較難維護,需添加詳細注釋。兼容性 :反射可能因JDK版本或類結構變化而失效。
總結
Class
類是Java反射的基石,通過它可以在運行時動態獲取和操作類信息。核心方法涵蓋類結構解析、實例化、字段/方法訪問等場景,但在生產環境中需謹慎使用,權衡靈活性與性能、安全性的關系。