最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java反射機制核心類Class、Constructor、Method、Field詳解

 更新時間:2025年12月10日 09:34:45   作者:梵得兒SHI  
反射機制是Java語言的一項強大特性,允許程序在運行時動態(tài)地加載、探知和使用類或者對象的信息,這篇文章主要介紹了Java反射機制核心類Class、Constructor、Method、Field的相關資料,需要的朋友可以參考下

反射是 Java 中一種強大的動態(tài)編程機制,它允許程序在運行時獲取類的元數(shù)據(jù)(如類名、屬性、方法、構造器等),并動態(tài)操作類的成員(即使是私有成員)。這種特性讓 Java 具備了極高的靈活性,也是 Spring、MyBatis 等框架的核心底層技術。

本文將深入剖析反射機制的四大核心類:Class(類對象)、Constructor(構造方法)、Method(成員方法)、Field(成員屬性),結合實例和圖解,幫你徹底搞懂反射的工作原理。

一、反射的 “入口”:Class 類(類對象)

Class類是反射的基礎 —— 它是所有類的 “元數(shù)據(jù)容器”。每個類在 JVM 中都有且僅有一個對應的Class對象,通過這個對象可以獲取該類的所有信息(屬性、方法、構造器等)。

1. 什么是 Class 對象?

當一個類被加載到 JVM 時,JVM 會為其創(chuàng)建一個Class類型的對象(注意:Class本身也是一個類),這個對象包含了該類的完整結構信息。我們可以把Class對象理解為 “類的說明書”,通過它能知道這個類有哪些屬性、方法、構造器,以及類的繼承關系等。

2. 獲取 Class 對象的 3 種方式

獲取Class對象是反射操作的第一步,常用的有 3 種方式,適用場景不同:

方式代碼示例特點
對象調用getClass()User user = new User(); Class<?> clazz = user.getClass();需先創(chuàng)建對象,適合已有實例的場景
類名直接訪問.classClass<?> clazz = User.class;無需創(chuàng)建對象,不會觸發(fā)類的初始化(僅加載)
Class.forName()Class<?> clazz = Class.forName("com.example.User");僅需類的全限定名,會觸發(fā)類的初始化(執(zhí)行靜態(tài)代碼塊),適合動態(tài)加載類

3. Class 類的核心方法

Class類提供了大量方法用于獲取類的元數(shù)據(jù),核心方法如下:

  • 獲取類名:getName()(全限定名)、getSimpleName()(簡單類名)
  • 獲取構造器:getConstructor(Class<?>...)(公共構造器)、getDeclaredConstructor(Class<?>...)(所有構造器,包括私有)
  • 獲取方法:getMethod(String, Class<?>...)(公共方法,包括繼承的)、getDeclaredMethod(String, Class<?>...)(本類所有方法,包括私有)
  • 獲取屬性:getField(String)(公共屬性,包括繼承的)、getDeclaredField(String)(本類所有屬性,包括私有)
  • 判斷類類型:isInterface()、isEnum()、isArray()

4. 示例:通過 Class 對象獲取類信息

public class User {
    private String name;
    private int age;

    public User() {}

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void sayHello() {
        System.out.println("Hello, " + name);
    }
}

// 測試類
public class ReflectionDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        // 獲取Class對象(3種方式任選)
        Class<?> clazz = Class.forName("com.example.User");

        // 獲取類名
        System.out.println("全限定名:" + clazz.getName()); // com.example.User
        System.out.println("簡單類名:" + clazz.getSimpleName()); // User

        // 獲取所有公共構造器
        Constructor<?>[] constructors = clazz.getConstructors();
        for (Constructor<?> c : constructors) {
            System.out.println("公共構造器:" + c);
        }

        // 獲取所有公共方法
        Method[] methods = clazz.getMethods();
        for (Method m : methods) {
            System.out.println("公共方法:" + m);
        }
    }
}

5. 圖解 Class 類的角色

上圖展示了核心關系:

  • 每個類(如User)在 JVM 中對應唯一的Class對象;
  • 類的所有實例(user1、user2)都可以通過getClass()獲取同一個Class對象;
  • Class對象存儲了類的完整元數(shù)據(jù),是反射的 “入口”。

二、構造方法的 “操縱者”:Constructor 類

Constructor類用于描述類的構造方法,通過它可以在運行時創(chuàng)建類的實例(即使是私有構造方法)。

1. 獲取 Constructor 對象

通過Class對象的方法獲取Constructor

  • getConstructor(Class<?>... parameterTypes):獲取公共構造器(參數(shù)為構造器的參數(shù)類型);
  • getDeclaredConstructor(Class<?>... parameterTypes):獲取所有構造器(包括私有);
  • getConstructors():獲取所有公共構造器(返回數(shù)組);
  • getDeclaredConstructors():獲取所有構造器(包括私有,返回數(shù)組)。

2. 創(chuàng)建對象:newInstance ()

獲取Constructor對象后,調用newInstance(Object... initArgs)方法即可創(chuàng)建實例,參數(shù)為構造方法的入?yún)ⅰ?/p>

注意:如果是私有構造器,需要先調用setAccessible(true)突破訪問權限(否則會拋IllegalAccessException)。

3. 示例:通過 Constructor 創(chuàng)建對象

public class ReflectionDemo {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = User.class;

        // 獲取無參構造器(公共)
        Constructor<?> constructor1 = clazz.getConstructor();
        User user1 = (User) constructor1.newInstance(); // 等價于 new User()

        // 獲取有參構造器(公共)
        Constructor<?> constructor2 = clazz.getConstructor(String.class, int.class);
        User user2 = (User) constructor2.newInstance("張三", 20); // 等價于 new User("張三", 20)

        // 獲取私有構造器(假設User有一個私有構造器:private User(String name))
        Constructor<?> constructor3 = clazz.getDeclaredConstructor(String.class);
        constructor3.setAccessible(true); // 開啟訪問權限
        User user3 = (User) constructor3.newInstance("李四"); // 成功創(chuàng)建私有構造器實例
    }
}

4. 圖解 Constructor 的作用

上圖展示:

  • Class對象包含類的所有構造器(通過Constructor對象表示);
  • 每個Constructor對象對應一個構造方法,通過newInstance()可創(chuàng)建實例;
  • 私有構造器需要通過setAccessible(true)開啟訪問權限。

三、方法的 “執(zhí)行者”:Method 類

Method類用于描述類的成員方法,通過它可以在運行時調用任意方法(包括私有方法和靜態(tài)方法)。

1. 獲取 Method 對象

通過Class對象的方法獲取Method

  • getMethod(String name, Class<?>... parameterTypes):獲取公共方法(包括繼承的,參數(shù)為方法名和參數(shù)類型);
  • getDeclaredMethod(String name, Class<?>... parameterTypes):獲取本類所有方法(包括私有,不包括繼承的);
  • getMethods():獲取所有公共方法(包括繼承的,返回數(shù)組);
  • getDeclaredMethods():獲取本類所有方法(包括私有,返回數(shù)組)。

2. 調用方法:invoke ()

獲取Method對象后,調用invoke(Object obj, Object... args)方法即可執(zhí)行方法:

  • obj:調用方法的實例(靜態(tài)方法可傳null);
  • args:方法的入?yún)ⅰ?/li>

注意:私有方法需要先調用setAccessible(true)突破權限。

3. 示例:通過 Method 調用方法

public class ReflectionDemo {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = User.class;
        User user = new User("張三", 20);

        // 獲取公共實例方法sayHello()
        Method sayHelloMethod = clazz.getMethod("sayHello");
        sayHelloMethod.invoke(user); // 輸出:Hello, 張三

        // 獲取私有方法(假設User有私有方法:private void setAge(int age))
        Method setAgeMethod = clazz.getDeclaredMethod("setAge", int.class);
        setAgeMethod.setAccessible(true); // 開啟訪問權限
        setAgeMethod.invoke(user, 25); // 調用私有方法

        // 獲取靜態(tài)方法(假設User有靜態(tài)方法:public static void showVersion())
        Method showVersionMethod = clazz.getMethod("showVersion");
        showVersionMethod.invoke(null); // 靜態(tài)方法obj傳null
    }
}

4. 圖解 Method 的作用

上圖展示:

  • Class對象包含類的所有方法(通過Method對象表示);
  • 調用實例方法時,invoke()的第一個參數(shù)為實例對象;
  • 調用靜態(tài)方法時,invoke()的第一個參數(shù)為null。

四、屬性的 “讀寫器”:Field 類

Field類用于描述類的成員屬性,通過它可以在運行時讀寫任意屬性(包括私有屬性)。

1. 獲取 Field 對象

通過Class對象的方法獲取Field

  • getField(String name):獲取公共屬性(包括繼承的,參數(shù)為屬性名);
  • getDeclaredField(String name):獲取本類所有屬性(包括私有,不包括繼承的);
  • getFields():獲取所有公共屬性(包括繼承的,返回數(shù)組);
  • getDeclaredFields():獲取本類所有屬性(包括私有,返回數(shù)組)。

2. 讀寫屬性:get () 和 set ()

  • get(Object obj):獲取對象obj的該屬性值(靜態(tài)屬性objnull);
  • set(Object obj, Object value):設置對象obj的該屬性值(靜態(tài)屬性objnull)。

注意:私有屬性需要先調用setAccessible(true)突破權限。

3. 示例:通過 Field 讀寫屬性

public class ReflectionDemo {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = User.class;
        User user = new User("張三", 20);

        // 獲取私有屬性name
        Field nameField = clazz.getDeclaredField("name");
        nameField.setAccessible(true); // 開啟訪問權限
        String name = (String) nameField.get(user); // 讀值:張三
        nameField.set(user, "李四"); // 設值

        // 獲取私有屬性age
        Field ageField = clazz.getDeclaredField("age");
        ageField.setAccessible(true);
        int age = (int) ageField.get(user); // 讀值:20
        ageField.set(user, 25); // 設值

        // 獲取靜態(tài)屬性(假設User有靜態(tài)屬性:public static String version)
        Field versionField = clazz.getField("version");
        String version = (String) versionField.get(null); // 靜態(tài)屬性obj傳null
        versionField.set(null, "1.0.1");
    }
}

4. 圖解 Field 的作用

上圖展示:

  • Class對象包含類的所有屬性(通過Field對象表示);
  • 讀寫實例屬性時,get()/set()的參數(shù)為實例對象;
  • 讀寫靜態(tài)屬性時,get()/set()的參數(shù)為null。

五、反射的優(yōu)缺點與應用場景

優(yōu)點

  1. 動態(tài)性:運行時獲取類信息并操作,突破編譯期限制(如動態(tài)加載未知類);
  2. 靈活性:可操作私有成員,適合框架開發(fā)(如 Spring 的依賴注入);
  3. 通用性:統(tǒng)一處理不同類的對象(如 ORM 框架映射數(shù)據(jù)庫字段)。

缺點

  1. 性能開銷:反射操作繞過編譯期檢查,比直接調用慢(約 10-100 倍);
  2. 安全性問題setAccessible(true)可突破訪問權限,可能破壞封裝性;
  3. 代碼可讀性差:反射代碼較繁瑣,不如直接調用直觀。

典型應用場景

  • 框架底層:Spring IOC(通過反射創(chuàng)建 Bean)、MyBatis(通過反射映射結果集);
  • 注解處理:JUnit 的@Test、Spring 的@Autowired(通過反射解析注解);
  • 動態(tài)代理:AOP 的實現(xiàn)基礎(通過反射增強方法);
  • 序列化 / 反序列化:JSON 框架(如 Jackson)通過反射讀寫對象屬性。

六、總結

反射機制的四大核心類分工明確:

  • Class:反射的入口,存儲類的元數(shù)據(jù);
  • Constructor:操縱構造方法,創(chuàng)建對象;
  • Method:執(zhí)行任意方法(包括私有、靜態(tài));
  • Field:讀寫任意屬性(包括私有、靜態(tài))。

掌握反射不僅能理解框架底層原理,更能在需要動態(tài)編程的場景中(如工具類開發(fā))發(fā)揮巨大作用。但需注意:反射是 “雙刃劍”,應避免在性能敏感場景濫用,且需謹慎處理訪問權限問題。

到此這篇關于Java反射機制核心類Class、Constructor、Method、Field的文章就介紹到這了,更多相關Java Class、Constructor、Method、Field內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • spring 集成 mybatis的實例詳解

    spring 集成 mybatis的實例詳解

    這篇文章主要介紹了spring 集成 mybatis的實例詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • Java基礎學習之集合底層原理

    Java基礎學習之集合底層原理

    今天帶大家回顧Java基礎的相關知識,文中對集合底層原理作了非常詳細的圖文介紹,對Java初學者有非常好的幫助,需要的朋友可以參考下
    2021-05-05
  • java異步導出的實現(xiàn)過程

    java異步導出的實現(xiàn)過程

    這篇文章主要介紹了java異步導出的實現(xiàn)過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-10-10
  • Java將集合元素轉換為數(shù)組的三種方式

    Java將集合元素轉換為數(shù)組的三種方式

    在實際開發(fā)中,雖然用集合來存儲元素通常更靈活,但有些場景下,我們?nèi)匀恍枰獙⒓限D換成數(shù)組,下面就來介紹一下Java將集合元素轉換為數(shù)組的三種方式,感興趣的可以了解一下
    2025-11-11
  • JAVA中的日期時間類用法總結

    JAVA中的日期時間類用法總結

    這篇文章主要給大家介紹了關于JAVA中日期時間類用法的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • Java集合案例之斗地主游戲

    Java集合案例之斗地主游戲

    這篇文章主要為大家詳細介紹了Java集合案例之斗地主游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 程序猿必須要掌握的多線程安全問題之鎖策略詳解

    程序猿必須要掌握的多線程安全問題之鎖策略詳解

    在筆者面試過程時,經(jīng)常會被問到各種各樣的鎖,如樂觀鎖、讀寫鎖等等,非常繁多,在此做一個總結,介紹的內(nèi)容如下,需要的朋友可以參考下
    2021-06-06
  • SpringBoot的自動配置原理解析

    SpringBoot的自動配置原理解析

    這篇文章主要介紹了SpringBoot的自動配置原理解析,SpringBoot的自動配置要從它的啟動類@SpringBootApplication說起,點進注解,@Target設置當前注解可以標記在哪,(ElementType.type)表示標注在類上面,需要的朋友可以參考下
    2023-08-08
  • Java實現(xiàn)電影院訂票系統(tǒng)代碼

    Java實現(xiàn)電影院訂票系統(tǒng)代碼

    這篇文章主要介紹了Java實現(xiàn)電影院訂票系統(tǒng)代碼,代碼實現(xiàn)了界面類登錄注冊類,用戶類等,具有一定參考價值,需要的朋友可以參考下。
    2017-11-11
  • 深入解析 Java Future 類及代碼示例

    深入解析 Java Future 類及代碼示例

    Java Future是java.util.concurrent包中用于表示異步計算結果的核心接口,下面給大家介紹Java Future 類及實例代碼,感興趣的朋友一起看看吧
    2025-06-06

最新評論

尚义县| 平舆县| 西平县| 蒙自县| 祁门县| 缙云县| 孝昌县| 福建省| 大洼县| 迁西县| 阿勒泰市| 东山县| 芜湖市| 富蕴县| 庆城县| 新田县| 平度市| 稷山县| 南充市| 虎林市| 合水县| 高安市| 甘谷县| 安陆市| 武清区| 遂川县| 温宿县| 乐清市| 黔江区| 琼中| 江川县| 郎溪县| 北碚区| 泽州县| 九龙坡区| 酉阳| 泰兴市| 荔浦县| 乐东| 萝北县| 呼玛县|