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

Java 反射機制核心:getClass() 與 Class 對象深度解析

     編輯:Java 程式設計入門

反射是 Java 動態性的基石,允許運行時檢查類、接口、字段和方法的信息。getClass() 是進入反射世界的鑰匙,本文深度解析 Class 對象的獲取方式、類型信息提取及實際應用場景。

一、獲取 Class 對象的三種方式

1. 對象實例調用 getClass()

String str = "Hello";
Class<?> clazz = str.getClass();  // 返回 String.class

2. 類字面量 .class

Class<String> clazz = String.class;
Class<int> intClass = int.class;  // 基本類型也有 Class 對象
Class<String[]> arrClass = String[].class;  // 數組類型

3. Class.forName() 動態加載

Class<?> clazz = Class.forName("java.lang.String");
// 拋出 ClassNotFoundException,需捕獲

區別:前兩種在編譯期確定類型,第三種支持運行時動態決定,是框架開發的核心。

二、Class 對象包含的類型信息

基本信息獲取

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

四、實戰應用場景

1. 註解處理器

if (clazz.isAnnotationPresent(Table.class)) {
    Table table = clazz.getAnnotation(Table.class);
    String tableName = table.value();
}

2. 依賴注入框架核心邏輯

public <T> T createInstance(Class<T> clazz) {
    Constructor<T> ctor = findInjectableConstructor(clazz);
    Object[] args = resolveDependencies(ctor.getParameterTypes());
    return ctor.newInstance(args);
}

3. 動態代理輔助

Class<?>[] interfaces = clazz.getInterfaces();
Proxy.newProxyInstance(clazz.getClassLoader(), interfaces, handler);

五、性能與安全考量

  • 緩存 Class 對象:Class.forName() 較重,建議緩存
  • setAccessible(true):訪問私有成員需開啟,但會破壞封裝,慎用
  • 模塊化系統限制:Java 9+ 強封裝,需 --add-opens 導出包
  • 反射調用開銷:比直接調用慢 10-100 倍,熱點路徑避免使用

總結

Class 對象是 JVM 中類型信息的運行時表達,getClass()、.class、Class.forName() 三條獲取路徑各有適用場景。掌握反射 API,是理解 Spring、Hibernate、MyBatis 等主流框架原理的前提,也是構建動態化、可擴展系統的關鍵技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved