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

深入了解Java中的反射機(jī)制(reflect)

 更新時(shí)間:2023年05月21日 08:37:09   作者:無聲編碼器  
Java的反射機(jī)制允許我們對一個(gè)類的加載、實(shí)例化、調(diào)用方法、操作屬性的時(shí)期改為在運(yùn)行期進(jìn)行,這大大提高了代碼的靈活度,本文就來簡單講講反射機(jī)制的具體使用方法吧

Java的反射機(jī)制允許我們對一個(gè)類的加載、實(shí)例化、調(diào)用方法、操作屬性的時(shí)期改為在運(yùn)行期進(jìn)行,這大大提高了代碼的靈活度。但在運(yùn)行期進(jìn)行反射操作會(huì)消耗額外的資源與性能,所以要適度使用。

JVM(Java虛擬機(jī))加載一個(gè)類有以下幾種方式:

1、執(zhí)行代碼時(shí),需要用到某個(gè)類,例如:Person p = new Person(); 時(shí),這時(shí)候JVM 會(huì)加載 Person.class 。

2、通過反射機(jī)制中的:Class.forName(String className) 方法以字符串的形式加載指定的類,此方法只能尋找環(huán)境變量中配置的類路徑中指定的類。

3、通過類加載器 ClassLoader 來加載指定的類,類加載器可以額外指定環(huán)境變量中沒有指定的類路徑,并從中尋找指定的類進(jìn)行加載。

除了第一種方式外,剩下的兩種都是基于反射機(jī)制動(dòng)態(tài)的加載一個(gè)類,加載類的過程就是讓 JVM 讀取該類對應(yīng)的 class 文件。當(dāng) JVM 讀取一個(gè)類的 class 文件后,會(huì)實(shí)例化一個(gè) Class 類的實(shí)例用于保存加載的這個(gè)類的信息。并且每個(gè)被加載的類只會(huì)進(jìn)行一次加載過程,這意味著每個(gè)被 JVM 加載的類都會(huì)在 JVM 內(nèi)部以一個(gè) Class 類的實(shí)例進(jìn)行保存,所以每個(gè)類有且只有一個(gè) Class 類的實(shí)例與之對應(yīng)。Class 也稱為類對象,每個(gè)實(shí)例用于表示 JVM 加載的一個(gè)類,通過它可以獲取其表示的類的相關(guān)信息,比如類的名字、有哪些屬性、構(gòu)造器以及所有方法,并且通過 Class 還可以實(shí)例化其表示的類。

Class 類 與 Method 類

  • Class 類:Class 類的實(shí)例表示正在運(yùn)行的Java應(yīng)用程序中的類和接口。Class 類沒有公共構(gòu)造函數(shù),類對象是由Java虛擬機(jī)在加載類時(shí)自動(dòng)構(gòu)造的,通過調(diào)用類加載器中的defineClass方法來構(gòu)造。
  • Method 類:Method 類是反射API中一個(gè)重要的類,其每一個(gè)實(shí)例表示某個(gè)類的一個(gè)具體方法,所反映的方法可以是類方法或?qū)嵗椒ǎòǔ橄蠓椒ǎ?。通過 Method 可以獲取到其表示的方法的相關(guān)信息,如方法名、返回值類型、參數(shù)類型、訪問修飾符等。并且也可以通過 Method 類動(dòng)態(tài)調(diào)用其表示的方法。

方法實(shí)例

public static Class<?> forName(String className)
                throws ClassNotFoundException

描述:

返回與具有給定字符串名稱的類或接口關(guān)聯(lián)的Class對象。

參數(shù):

className -- 所需類的完全限定名稱。

返回值:

具有指定名稱的類的Class對象。

注意:

如果找不到類,拋出 ClassNotFoundException 異常。

public class Person {
    public String name;
    private Integer code;
    public Person() {
        System.out.println("無參構(gòu)造方法");
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        Class<?> aClass = Class.forName("Person");
        System.out.println(aClass);
    }
}
// 程序運(yùn)行結(jié)果如下:
// class Person
public T newInstance()
        throws InstantiationException, IllegalAccessException

描述:

創(chuàng)建由該 Class 對象表示的類的新實(shí)例。該方法調(diào)用當(dāng)前 Class 所表示的類的無參構(gòu)造方法,所以該類必須有無參構(gòu)造方法。

參數(shù):

返回值:

由該 class 表示的類的新分配的實(shí)例。

注意:

  • 如果類或其無參構(gòu)造函數(shù)不可訪問,拋出 IllegalAccessException 異常。
  • 如果該類表示抽象類、接口、數(shù)組類、基元類型或void;或者如果該類沒有無參構(gòu)造函數(shù);或者如果實(shí)例化由于某些其他原因而失敗,拋出 InstantiationException 異常。
public class Person {
    public String name;
    private Integer code;
    public Person() {
        System.out.println("調(diào)用了無參構(gòu)造方法");
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        Class<?> aClass = Class.forName("Person");
        Person person = (Person)aClass.newInstance();
        System.out.println(person);
    }
}
// 程序運(yùn)行結(jié)果如下:
// 調(diào)用了無參構(gòu)造方法
// Person@29453f44
public Constructor<T> getConstructor(Class<?>... parameterTypes)
        throws NoSuchMethodException, SecurityException

描述:

返回一個(gè)構(gòu)造函數(shù)對象,該對象反映由該Class對象表示的類的指定公共構(gòu)造函數(shù)。

參數(shù):

parameterTypes -- Class對象的數(shù)組,這些對象按聲明的順序標(biāo)識(shí)構(gòu)造函數(shù)的形式參數(shù)類型。

返回值:

與指定的parameterTypes匹配的公共構(gòu)造函數(shù)的Constructor對象。

注意:

  • 如果找不到匹配的方法,拋出 NoSuchMethodException 異常。
  • 如果訪問被拒絕,拋出 SecurityException 異常。
public class Person {
    public String name;
    private Integer code;
    public Person(String name) {
        this.name = name;
        System.out.println("調(diào)用了有參構(gòu)造方法");
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        Class<?> aClass = Class.forName("Person");
        Constructor constructor = aClass.getConstructor(String.class);
        Person person = (Person)constructor.newInstance("阿剛");
        System.out.println(person.name);
    }
}
// 程序運(yùn)行結(jié)果如下:
// 調(diào)用了有參構(gòu)造方法
// 阿剛
// Class 類
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
        throws NoSuchMethodException, SecurityException

描述:

獲取當(dāng)前 Class 所表示的類定義的指定名字及參數(shù)列表的方法。

參數(shù):

  • name -- 方法的名稱。
  • parameterTypes -- 一組Class對象,這些對象按聲明的順序標(biāo)識(shí)方法的形式參數(shù)類型。

返回值:

與指定的名稱和參數(shù)匹配的此類的方法的Method對象。

注意:

  • 如果找不到匹配的方法,拋出 NoSuchMethodException 異常。
  • 如果名稱為null, 拋出 NullPointerException 異常。
  • 如果訪問被拒絕,拋出 SecurityException 異常。
// Method 類
public Object invoke(Object obj, Object... args)
        throws IllegalAccessException, IllegalArgumentException,
           InvocationTargetException

描述:

在具有指定參數(shù)的指定對象上調(diào)用此 method 對象表示的基礎(chǔ)方法。如果基礎(chǔ)方法是靜態(tài)的,則會(huì)忽略指定的 obj 參數(shù),它可能為 null。

參數(shù):

  • obj -- 如果通過該方法調(diào)用的是成員方法,因?yàn)槌蓡T方法屬于對象,那么調(diào)用該方法時(shí),使用該參數(shù)傳遞成員方法所屬對象。如果過該方法調(diào)用的是靜態(tài)方法,可以傳遞null。
  • args -- 方法的實(shí)際參數(shù),若該方法無參,傳入 null 即可。

注意:

  • 如果此Method對象正在強(qiáng)制執(zhí)行Java語言訪問控制,并且底層方法不可訪問,拋出 IllegalAccessException 異常。
  • 如果方法是實(shí)例方法,并且指定的對象參數(shù)不是聲明底層方法(或其子類或?qū)崿F(xiàn)者)的類或接口的實(shí)例;或者如果實(shí)際參數(shù)和形式參數(shù)的數(shù)量不同;或者如果原始參數(shù)的展開轉(zhuǎn)換失?。换蛘呷绻诳赡艿恼归_之后,無法通過方法調(diào)用轉(zhuǎn)換將參數(shù)值轉(zhuǎn)換為相應(yīng)的形式參數(shù)類型; 拋出 IllegalArgumentException 異常。
  • 如果基礎(chǔ)方法拋出異常,則拋出 InvocationTargetException 異常。
  • 如果指定的對象為null,并且該方法是實(shí)例方法,則拋出 NullPointerException 異常。
public class Person {
    public String name;
    private Integer code;
    public Person() {
        System.out.println("調(diào)用了無參構(gòu)造方法");
    }
    public Person(String name) {
        this.name = name;
        System.out.println("調(diào)用了有參構(gòu)造方法");
    }
    public  static String happy(){
        return "哈哈";
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        Class<?> aClass = Class.forName("Person");
        Object person =  aClass.newInstance();
        // Method是反射API中一個(gè)重要的類,其每一個(gè)實(shí)例表示某個(gè)類的具體方法
        // 調(diào)用 setName 方法
        Method setMethod = aClass.getDeclaredMethod("setName",String.class);
        setMethod.invoke(person,"阿全");
        // 調(diào)用 getName 方法
        Method getMethod = aClass.getDeclaredMethod("getName",null);
        System.out.println(getMethod.invoke(person,null));
        // 調(diào)用了靜態(tài)方法
        Method happyMethod = aClass.getDeclaredMethod("happy",null);
        System.out.println(happyMethod.invoke(null,null));
    }
}
// 程序運(yùn)行結(jié)果如下:
// 調(diào)用了無參構(gòu)造方法
// 阿全
// 哈哈

以上就是深入了解Java中的反射機(jī)制(reflect)的詳細(xì)內(nèi)容,更多關(guān)于Java反射機(jī)制的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java存儲(chǔ)數(shù)據(jù)至Rredis之@RedisHash實(shí)現(xiàn)過程

    Java存儲(chǔ)數(shù)據(jù)至Rredis之@RedisHash實(shí)現(xiàn)過程

    文章介紹了在項(xiàng)目啟動(dòng)時(shí)通過@RedisHash注解,將Java對象映射為Redis中的Hash結(jié)構(gòu),實(shí)現(xiàn)數(shù)據(jù)的自動(dòng)加載與管理,具體步驟包括引入依賴、創(chuàng)建實(shí)體類、實(shí)現(xiàn)Repository,并完成增刪查改操作
    2025-10-10
  • Java如何識(shí)別圖片或掃描PDF中的文字詳解

    Java如何識(shí)別圖片或掃描PDF中的文字詳解

    這篇文章主要介紹了Java如何識(shí)別圖片或掃描PDF中文字的相關(guān)資料,介紹了Java中使用Spire.OCRforJava庫來識(shí)別圖片和掃描PDF文件中的文字,需要的朋友可以參考下
    2025-01-01
  • java bootclasspath的具體用法

    java bootclasspath的具體用法

    本文主要介紹了java bootclasspath的具體用法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • Java Atomic類及線程同步新機(jī)制原理解析

    Java Atomic類及線程同步新機(jī)制原理解析

    這篇文章主要介紹了Java Atomic類及線程同步新機(jī)制原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Java詳解使用線程池處理任務(wù)方法

    Java詳解使用線程池處理任務(wù)方法

    java中經(jīng)常需要用到多線程來處理,我們非常不建議單純使用繼承Thread或者實(shí)現(xiàn)Runnable接口的方式來創(chuàng)建線程,那樣勢必有創(chuàng)建及銷毀線程耗費(fèi)資源、線程上下文切換問題。同時(shí)創(chuàng)建過多的線程也可能引發(fā)資源耗盡的風(fēng)險(xiǎn),這個(gè)時(shí)候引入線程池比較合理,方便線程任務(wù)的管理
    2022-05-05
  • 詳解Spring MVC的攔截器與異常處理機(jī)制

    詳解Spring MVC的攔截器與異常處理機(jī)制

    這篇文章主要為大家詳細(xì)介紹了Spring MVC的攔截器與異常處理機(jī)制,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • SpringBoot執(zhí)行有返回值的異步任務(wù)問題

    SpringBoot執(zhí)行有返回值的異步任務(wù)問題

    這篇文章主要介紹了SpringBoot執(zhí)行有返回值的異步任務(wù)問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Mybatis-Plus更新操作時(shí)遇到的問題及解決方法

    Mybatis-Plus更新操作時(shí)遇到的問題及解決方法

    在MyBatis-Plus開啟邏輯刪除時(shí),使用updateById更新邏輯刪除字段時(shí),可能會(huì)出現(xiàn)看起來執(zhí)行了但實(shí)際上沒有更新的問題,下面給大家介紹Mybatis-Plus更新操作時(shí)遇到的問題及解決方法,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • IDEA為類和方法設(shè)置注解模板過程

    IDEA為類和方法設(shè)置注解模板過程

    本文主要講述了在IntelliJ IDEA中創(chuàng)建類和方法注解模板的步驟與實(shí)際效果,并提供了兩種方法注解模板的具體實(shí)現(xiàn)過程,通過自定義模板,用戶可以自動(dòng)化地生成類和方法的注釋,提高開發(fā)效率
    2026-04-04
  • Java精品項(xiàng)目瑞吉外賣之員工新增篇

    Java精品項(xiàng)目瑞吉外賣之員工新增篇

    這篇文章主要為大家詳細(xì)介紹了java精品項(xiàng)目-瑞吉外賣訂餐系統(tǒng),此項(xiàng)目過大,分為多章獨(dú)立講解,本篇內(nèi)容為新增員工功能的實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05

最新評論

阿克陶县| 二连浩特市| 囊谦县| 德阳市| 临江市| 凌源市| 清徐县| 保康县| 毕节市| 巍山| 修水县| 崇义县| 青冈县| 日照市| 隆回县| 万山特区| 民乐县| 乌海市| 固安县| 鄂托克前旗| 绩溪县| 洛川县| 同仁县| 洪雅县| 连平县| 谷城县| 新和县| 宝兴县| 平乡县| 麻城市| 乐都县| 衡南县| 肇东市| 全南县| 察隅县| 宜阳县| 呼伦贝尔市| 太保市| 陆河县| 海丰县| 屯昌县|