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

Java中反射機制的使用詳解

 更新時間:2023年09月19日 08:38:03   作者:_雨_  
這篇文章主要介紹了Java中反射機制的使用詳解,Java的發(fā)射機制允許程序在運行時檢查和操作任意一個類、方法、屬性等的信息,包括了類名、方法名、屬性名、參數(shù)列表以及訪問修飾符等,需要的朋友可以參考下

反射的基本介紹

Java的發(fā)射機制(Reflection)是指在運行時動態(tài)地獲取類的信息并操作對象的能力。

Java的發(fā)射機制允許程序在運行時檢查和操作任意一個類、方法、屬性等的信息,包括了類名、方法名、屬性名、參數(shù)列表以及訪問修飾符等。

通過Java的發(fā)射機制,可以實現(xiàn)一些高級的功能,比如動態(tài)生成代理對象、動態(tài)生成類、動態(tài)配置對象等。同時,Java的一些框架也廣泛應用了發(fā)射機制,比如Spring框架中大量使用了反射機制來實現(xiàn)依賴注入和AOP等功能。

Java中一些常用的反射API包括Class、Method、Field、Constructor等。其中,Class類是反射機制的核心,通過它可以獲取一個類的所有信息。Method和Field則分別表示類中的方法和屬性,Constructor則表示類中的構(gòu)造方法。

Java的發(fā)射機制給Java編程帶來了更大的靈活性,但同時也需要注意到發(fā)射機制的運行效率相對較低,同時也可能破壞類的封裝性,因此在使用時需要謹慎考慮。

在了解反射的基本介紹之后,我們在來看看反射的需求,為什么會需要反射

先看一段代碼

代碼演示:

package com.reflection.question;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
/**
 * 反射問題的引入
 */
@SuppressWarnings({"all"})
public class ReflectionQuestion {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        //根據(jù)配置文件 re.properties 指定信息, 創(chuàng)建Cat對象并調(diào)用方法hi
        //傳統(tǒng)的方式 new 對象 -》 調(diào)用方法
//        Cat cat = new Cat();
//        cat.hi(); ===> cat.cry() 修改源碼.
        //我們嘗試做一做 -> 明白反射
        //1. 使用Properties 類, 可以讀寫配置文件    Properties的底層就是HashTable
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\re.properties"));//加載配置文件的鍵值對到properties對象
        String classfullpath = properties.get("classfullpath").toString();//"com.hspedu.Cat"  根據(jù)鍵獲取值
        String methodName = properties.get("method").toString();//"hi"
        System.out.println("classfullpath=" + classfullpath);
        System.out.println("method=" + methodName);
        //2. 創(chuàng)建對象 , 傳統(tǒng)的方法,行不通 =》 反射機制
        //new classfullpath();
        //3. 使用反射機制解決
        //(1) 加載類, 返回Class類型的對象cls
        Class cls = Class.forName(classfullpath);
        //(2) 通過 cls 得到你加載的類 com.hspedu.Cat 的對象實例
        Object o = cls.newInstance();
        System.out.println("o的運行類型=" + o.getClass()); //運行類型
        //(3) 通過 cls 得到你加載的類 com.hspedu.Cat 的 methodName"hi"  的方法對象
        //    即:在反射中,可以把方法視為對象(萬物皆對象)
        Method method1 = cls.getMethod(methodName);
        //(4) 通過method1 調(diào)用方法: 即通過方法對象來實現(xiàn)調(diào)用方法
        System.out.println("=============================");
        method1.invoke(o); //傳統(tǒng)方法 對象.方法() , 反射機制 方法.invoke(對象)
    }
}

反射的需求

Java反射機制的需求主要有以下幾個方面:

  1. 動態(tài)加載類和調(diào)用類方法:通過反射機制,可以在運行時動態(tài)的加載一個類,并調(diào)用該類的方法。這種方式可以實現(xiàn)更加靈活的代碼編寫,避免了在編譯期就要確定所有的類和方法的限制。
  2. 實現(xiàn)通用框架:通過反射機制,可以實現(xiàn)通用的框架,比如ORM(對象-關系映射)框架、依賴注入框架、AOP(面向切面編程)框架等。這些框架需要在運行時動態(tài)的獲取類的信息,然后進行相應的操作。
  3. 修改類的屬性和方法:通過反射機制,可以在運行時修改類的屬性和方法,從而實現(xiàn)更加靈活的代碼編寫。
  4. 實現(xiàn)序列化和反序列化:Java中的序列化和反序列化需要用到反射機制,通過反射機制可以獲取對象的屬性和方法,然后將其序列化為字節(jié)流或者反序列化為對象。
  5. 動態(tài)代理:通過反射機制,可以實現(xiàn)動態(tài)代理,即在運行時生成一個代理對象,通過代理對象來調(diào)用目標對象的方法,從而實現(xiàn)AOP等功能。

那么我們使用反射機制可以完成

1.在運行時判斷任意一個對象所屬的類

2.在運行時構(gòu)造任意一個類的對象

3.在運行時得到任意一個類所具有的成員變量和方法

4.在運行時調(diào)用任意一個對象的成員變量和方法

5.生成動態(tài)代理

反射相關的主要類

1.java.lang.Class:代表一個類,Class對象表示某個類加載后在堆中的對象

2.java.lang.reflect.Method: 代表類的方法, Method對象表示某個類的方法

3.java.lang.reflect.Field: 代表類的成員變量,Field對象表示某個類的成員變量

4.java.lang.reflect.Constructor: 代表類的構(gòu)造方法,Constructor對象表示構(gòu)造器

代碼演示:

注意:反射和我們正常的使用方式有些不同,我們正常調(diào)用方法時對象名.方法名,但是在反射中是 方法名.對象名這里要注意一下

package com.reflection;
import java.io.FileInputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;
@SuppressWarnings({"all"})
public class Reflection01 {
    public static void main(String[] args) throws Exception {
        //1. 使用Properties 類, 可以讀寫配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\re.properties"));
        String classfullpath = properties.get("classfullpath").toString();//"com.hspedu.Cat"
        String methodName = properties.get("method").toString();//"hi"
        //2. 使用反射機制解決
        //(1) 加載類, 返回Class類型的對象cls
        Class cls = Class.forName(classfullpath);
        //(2) 通過 cls 得到你加載的類 com.hspedu.Cat 的對象實例
        Object o = cls.newInstance();
        System.out.println("o的運行類型=" + o.getClass()); //運行類型
        //(3) 通過 cls 得到你加載的類 com.hspedu.Cat 的 methodName"hi"  的方法對象
        //    即:在反射中,可以把方法視為對象(萬物皆對象)
        Method method1 = cls.getMethod(methodName);
        //(4) 通過method1 調(diào)用方法: 即通過方法對象來實現(xiàn)調(diào)用方法
        System.out.println("=============================");
        method1.invoke(o); //傳統(tǒng)方法 對象.方法() , 反射機制 方法.invoke(對象)
        //java.lang.reflect.Field: 代表類的成員變量, Field對象表示某個類的成員變量
        //得到name字段
        //getField不能得到私有的屬性
        Field nameField = cls.getField("age"); //
        System.out.println(nameField.get(o)); // 傳統(tǒng)寫法 對象.成員變量 , 反射 :  成員變量對象.get(對象)
        //java.lang.reflect.Constructor: 代表類的構(gòu)造方法, Constructor對象表示構(gòu)造器
        Constructor constructor = cls.getConstructor(); //()中可以指定構(gòu)造器參數(shù)類型, 返回無參構(gòu)造器
        System.out.println(constructor);//Cat()
        Constructor constructor2 = cls.getConstructor(String.class); //這里傳入的 String.class 就是String類的Class對象
        System.out.println(constructor2);//Cat(String name)
    }
}

反射優(yōu)點和缺點

優(yōu)點:

  • 動態(tài)性:Java反射機制可以在運行時動態(tài)地獲取類的信息和操作對象,使程序更加靈活和易于擴展。
  • 通用性:可以通過反射機制操作任意類型的對象,無需知道對象的具體類型。
  • 代碼復用性:反射機制可以讓代碼更加通用和復用,提高開發(fā)效率。
  • AOP支持:反射機制是實現(xiàn)AOP(面向切面編程)的重要手段之一。

缺點:

  • 性能較低:Java反射機制需要在運行時動態(tài)地獲取對象信息和方法,需要一定的時間開銷,因此性能較低。
  • 安全問題:反射機制可以操作任意類型的對象,容易造成安全問題,需要謹慎使用,并在必要時進行安全檢查。
  • 可讀性下降:由于反射機制支持動態(tài)的獲取和操作對象,因此代碼的可讀性會下降一些,需要謹慎使用。
  • 不利于編譯器優(yōu)化:由于反射機制需要在運行時動態(tài)獲取對象信息和方法,因此編譯器很難對代碼進行優(yōu)化。

代碼演示;

在下面的代碼中 ,我們分別測試了,使用正常的方式去調(diào)用方法,和使用反射的方式去調(diào)用方法,并且在執(zhí)行方法開始之前記錄了開始時間,在方法執(zhí)行結(jié)束之后,記錄了結(jié)束時間,最后兩個相減,就可以得到方法的執(zhí)行時間,我們就可以看出,使用正常的方式去調(diào)用方法,和使用反射的方式去調(diào)用方法,的區(qū)別。

package com.reflection;
import com.Cat;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
 * 測試反射調(diào)用a的性能,和優(yōu)化方案
 */
public class Reflection02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //Field
        //Method
        //Constructor
        m1();
        m2();
        m3();
    }
    //傳統(tǒng)方法來調(diào)用hi
    public static void m1() {
        Cat cat = new Cat();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 90; i++) {
            cat.hi();
        }
        long end = System.currentTimeMillis();
        System.out.println("m1() 耗時=" + (end - start));
    }
    //反射機制調(diào)用方法hi
    public static void m2() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class cls = Class.forName("com.Cat");
        Object o = cls.newInstance();
        Method hi = cls.getMethod("hi");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 900000000; i++) {
            hi.invoke(o);//反射調(diào)用方法
        }
        long end = System.currentTimeMillis();
        System.out.println("m2() 耗時=" + (end - start));
    }
    //反射調(diào)用優(yōu)化 + 關閉訪問檢查
    public static void m3() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class cls = Class.forName("com.Cat");
        Object o = cls.newInstance();
        Method hi = cls.getMethod("hi");
        hi.setAccessible(true);//在反射調(diào)用方法時,取消訪問檢查
        long start = System.currentTimeMillis();
        for (int i = 0; i < 900000000; i++) {
            hi.invoke(o);//反射調(diào)用方法
        }
        long end = System.currentTimeMillis();
        System.out.println("m3() 耗時=" + (end - start));
    }
}

反射調(diào)用優(yōu)化

Java中反射調(diào)用通常比直接調(diào)用方法緩慢,因為它需要進行額外的動態(tài)類型檢查和查找。為了優(yōu)化反射調(diào)用,可以采用以下幾種方法:

緩存Method對象:通過緩存Method對象,避免動態(tài)查找,提高調(diào)用效率。

使用方法句柄(MethodHandle):方法句柄是一種更高效的調(diào)用機制,它可以繞過反射調(diào)用的開銷。方法句柄比反射調(diào)用更快,特別是在熱代碼路徑上。

使用invokedynamic指令:為了提高反射調(diào)用的性能,Java 7引入了invokedynamic指令。它允許動態(tài)綁定方法調(diào)用,避免了反射調(diào)用的開銷。

使用字節(jié)碼生成庫:字節(jié)碼生成庫可以生成字節(jié)碼,從而避免了反射調(diào)用的開銷。比如,cglib是一個非常常用的字節(jié)碼生成庫。

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

相關文章

  • java中DES加密解密

    java中DES加密解密

    本文給大家分享的是一段java中實現(xiàn)des加密解密的代碼,非常的實用,基本每個項目都可以用到,推薦給大家。
    2015-03-03
  • Java正則表達式Pattern和Matcher原理詳解

    Java正則表達式Pattern和Matcher原理詳解

    這篇文章主要介紹了Java正則表達式Pattern和Matcher原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • 使用IntelliJ IDEA 15和Maven創(chuàng)建Java Web項目(圖文)

    使用IntelliJ IDEA 15和Maven創(chuàng)建Java Web項目(圖文)

    本篇文章主要介紹了使用IntelliJ IDEA 15和Maven創(chuàng)建Java Web項目(圖文),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • SpringMVC視圖轉(zhuǎn)發(fā)重定向區(qū)別及控制器詳解

    SpringMVC視圖轉(zhuǎn)發(fā)重定向區(qū)別及控制器詳解

    這篇文章主要為大家介紹了SpringMVC視圖轉(zhuǎn)發(fā)重定向區(qū)別及控制器示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • 使用@pathvariable與@requestparam碰到的一些問題及解決

    使用@pathvariable與@requestparam碰到的一些問題及解決

    這篇文章主要介紹了使用@pathvariable與@requestparam碰到的一些問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Logback配置文件這么寫,還說你不會整理日志?

    Logback配置文件這么寫,還說你不會整理日志?

    logback框架會默認加載classpath下命名為logback-spring.xml或logback.xml的配置文件。這篇文章主要介紹了Logback配置文件寫法,需要的朋友可以參考下
    2020-07-07
  • 談談為JAXB和response設置編碼,解決wechat4j中文亂碼的問題

    談談為JAXB和response設置編碼,解決wechat4j中文亂碼的問題

    中文亂碼是每個程序員都會遇到的問題,本篇文章主要介紹了談談為JAXB和response設置編碼,解決wechat4j中文亂碼的問題,具有一定的參考價值,有興趣的可以了解一下。
    2016-12-12
  • 使用Hibernate根據(jù)實體類自動生成表的方法

    使用Hibernate根據(jù)實體類自動生成表的方法

    這篇文章主要介紹了使用Hibernate根據(jù)實體類自動生成表的方法,該篇提供了兩種方法,可以根據(jù)需要選擇其一,希望對你有所幫助,如有不對的地方還望指正
    2023-03-03
  • springboot2.x整合redis知識點講解

    springboot2.x整合redis知識點講解

    在本篇文章中小編給大家分享的是一篇關于springboot2.x整合redis知識點內(nèi)容,有興趣的朋友們可以學習下。
    2020-01-01
  • Java泛型詳解

    Java泛型詳解

    本文給大家匯總介紹了下java中的泛型的相關資料,包括引入泛型機制的原因,泛型類,泛型方法,泛型的實現(xiàn)以及泛型的注意事項,非常的詳細,有需要的小伙伴可以參考下
    2016-03-03

最新評論

宁安市| 梨树县| 邹城市| 东光县| 罗定市| 嘉荫县| 通辽市| 新河县| 威宁| 从化市| 自贡市| 潜江市| 洛扎县| 玛多县| 沙雅县| 安康市| 雅安市| 平果县| 平遥县| 顺义区| 孟州市| 沛县| 海原县| 年辖:市辖区| 长春市| 梁河县| 湖州市| 宜川县| 章丘市| 买车| 株洲市| 波密县| 东光县| 资溪县| 策勒县| 山阴县| 开平市| 湾仔区| 安图县| 抚顺市| 无为县|