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

Java基礎之反射詳解

 更新時間:2021年05月12日 10:52:17   作者:福建選手阿俊  
這篇文章主要介紹了教你怎么通過IDEA設置堆內存空間,文中有非常詳細的代碼示例,對正在使用IDEA的小伙伴們很有幫助喲,需要的朋友可以參考下

前言

反射是我們框架的靈魂,反射也是我們框架的一個底層基石,沒有反射也就沒有框架,如果我們學好了反射,對我們閱讀框架底層是有很大班助的——阿俊。有些文章上來就講反射,就會很懵逼,不知道是干啥的,所以我們就引出一些問題來看看為什么需要反射

一、一個需求引出反射

看下面的問題
根據配置文件reflection.properties指定信息,創(chuàng)建People對象并調用方法hi

classullpath= com.reflection.People
method=hi

思考:使用現有技術,能做嗎?
我們可以來試一試
我們根據要求創(chuàng)建出兩個類和一個配置文件

在這里插入圖片描述

People 類

public class People {
    private String name="zlj";
    public void hi(){
        System.out.println("hi"+name);
    }
}
classullpath= com.reflection.People
method=hi

在QuestionReflectionQuestion類中進行測試,我們學Java的時候可知,可以通過如下的方法創(chuàng)建People對象并調用方法hi

public class QuestionReflectionQuestion {
    public static void main(String[] args) {
            //傳統(tǒng)方式
        People people = new People();
        people.hi();
    }
}

那我們如何通過配置文件reflection.properties指定信息,創(chuàng)建People對象并調用方法hi呢?

注意:這樣的需求在學習框架時特別多,即通過外部文件配置,在不修改源碼情況下,來控制程序,也符合設計模式的ocp原則(開閉原則:不修改源碼來擴展功能)

嘗試1:Java中有一個Properties類,可以讀寫配置文件,我們可以用它進行嘗試

public class QuestionReflectionQuestion {
    public static void main(String[] args) throws IOException {
        //我們嘗試做一下-》明白反射
        //Java中有一個Properties類,可以讀寫配置文件,我們可以用它進行嘗試
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\reflection.properties"));
        String classullpath = properties.get("classullpath").toString();//classullpath:com.reflection.People
        String method = properties.get("method").toString();//method:hi
        System.out.println("classullpath:"+classullpath);
        System.out.println("method:"+method);
        //那我們可以不可以直接使用new classullpath();來創(chuàng)建呢?這樣顯然不行的
    }
}

結論:嘗試失敗,我們就可以使用反射機制來解決上述:通過配置文件reflection.properties指定信息,創(chuàng)建People對象并調用方法hi,下一節(jié)進行代碼演示

二、反射入門

解決第一節(jié)問題的代碼演示

分四個步驟:

1.加載類,返回class類型對象:cls
2.通過cls得到你的加載類com.reflection.People的對象實例
3.通過cls得到你加載的類com.reflection.People的method=hi的方法對象(即:在反射中,可以把方法視為對象(即:萬物皆對象))
4.通過method調用方法:即通過方法對象來實現調用方法

public class QuestionReflectionQuestion {
    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\reflection.properties"));
        String classullpath = properties.get("classullpath").toString();//classullpath:com.reflection.People
        String methodName = properties.get("method").toString();//method:hi
        System.out.println("====使用反射機制解決=====");
        //1:加載類,返回class類型對象:cls
        Class cls = Class.forName(classullpath);
        //2:通過cls得到你的加載類com.reflection.People的對象實例
        Object o = cls.newInstance();
        System.out.println("o的運行類型="+o.getClass());//運行類型
        //3.通過cls得到你加載的類com.reflection.People的method=hi的方法對象
        //即:在反射中,可以把方法視為對象(即:萬物皆對象)
        Method method = cls.getMethod(methodName);
        //4.通過method調用方法:即通過方法對象來實現調用方法
        method.invoke(o);//傳統(tǒng)方法:對象.方法()    反射機制 方法.invoke(對象)
    }
}
====使用反射機制解決=====
o的運行類型=class com.reflection.People
hizlj

我們先知道一下反射實現方式的步驟即可,一些類的介紹,我們后續(xù)會進行介紹

如果Java沒有反射機制,Java就不是一種動態(tài)語言,而且我們所說的spring mybatis 框架就都不存在了,反射機制是框架的靈魂,也是底層機制的基石

反射機制的牛之處就在于:可以通過外部文件配置,在不修改源碼的情況下,來控制程序(這就是開閉原則)
比如,我們在People類中新增cry方法,我們就不需要在QuestionReflectionQuestion類中新增 people.cry();這個方法,只需要在配置文件中reflection.properties進行如下修改method=cry即可。

====使用反射機制解決=====
o的運行類型=class com.reflection.People
cryzlj

三、反射原理圖

前面我們對反射進行了一個快速入門,接下來,我們來介紹一下它的原理

反射機制允許程序在執(zhí)行期借助于ReflectionAPI取得任何類的內部信息(比如成員變量,構造器,成員方法等等),并能操作對象的屬性及方法。反射在設計模式和框架底層都會用到

加載完類之后,在堆中就產生了一個Class類型的對象(一個類只有一個Class對象) ,這個對象包含了類的完整結構信息。通過這個Class對象得到類的結構。這個對象就像一面鏡子, 透過這個鏡子看到類的結構,所以,形象的稱之為反射。

我們可以拿第一節(jié)的例子,畫圖來說明

在這里插入圖片描述

四、反射相關類

接下來講完反射機制原理,我們就來看一下反射機制可以做那些事情

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

2.在運行時構造任意一個類的對象

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

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

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

反射相關的主要類:

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

2.java.lang.reflect.Method:代表類的方法

3.java.lang.reflect.Field: 代表類的成員變量

4.java.lang.reflect.Constructor:代表類的構造方法

我們上面第二節(jié)介紹了Method演示,我們接下來進行Field和Constructor演示
People.java

public class People {
    public String name="zlj";
    public People(){
        this.name="zzg";
    }
    public People(String name){
        this.name=name;
    }
    public void hi(){
        System.out.println("hi"+name);
    }
    public void cry(){
        System.out.println("cry"+name);
    }
}

QuestionReflectionQuestion.java

public class QuestionReflectionQuestion {
    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\reflection.properties"));
        String classullpath = properties.get("classullpath").toString();//classullpath:com.reflection.People
        String methodName = properties.get("method").toString();//method:hi
        String fieldName = properties.get("field").toString();
        String constructorName = properties.get("constructor").toString();
        System.out.println("====使用反射機制解決=====");
        //1:加載類,返回class類型對象:cls
        Class cls = Class.forName(classullpath);
        //2:通過cls得到你的加載類com.reflection.People的對象實例
        Object o = cls.newInstance();
        System.out.println("o的運行類型="+o.getClass());//運行類型
        //3.通過cls得到你加載的類com.reflection.Field 的field=name的字段
        //即:在反射中,可以把方法視為對象(即:萬物皆對象)
        //getField不可以得到私有屬性
        Field field = cls.getField(fieldName);
        //4.通過field 調用方法:即通過方法對象來實現調用方法
        //因為對象賦了初始值;所以就是zzg,而不是zlj
        System.out.println(field.get(o));
        System.out.println("People類的字段name是否為zlj:"+field.equals("zlj"));
        //構造器的3,4和Field 一樣
        Constructor constructors = cls.getConstructor();//()中可以指定構造器參數類型。默認返回無參構造器
        System.out.println(constructors);
        Constructor constructor = cls.getConstructor(String.class);//傳入構造參數的類型對象
        System.out.println(constructor);
    }
}

reflection.properties

classullpath= com.reflection.People
method=cry
field=name
constructor=People

演示

====使用反射機制解決=====
o的運行類型=class com.reflection.People
People類的字段name是否為zlj:false
public com.reflection.People()
public com.reflection.People(java.lang.String)

五、反射調用優(yōu)化

前面我們說了反射的原理和反射的作用,接下來我們就說一下它的優(yōu)缺點

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

優(yōu)點:可以動態(tài)的創(chuàng)建和使用對象(也是框架底層核心),使用靈活沒有反射機制,框架技術就失去底層支撐。

缺點:使用反射基本是解釋執(zhí)行,對執(zhí)行速度有影響。

基于缺點,我們可以進行反射調用優(yōu)化。
我們先看一下傳統(tǒng)方法調用和反射機制調用的耗時

public class ReflectionOptimize {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        ReflectionOptimize.m1();
        ReflectionOptimize.m2();
    }
    //傳統(tǒng)方法調用hi
    public static void m1(){
        People people = new People();
        long start = System.currentTimeMillis();
        for (int i=0;i<900000;i++){
            people.hi();
        }
        long end = System.currentTimeMillis();
        System.out.println("傳統(tǒng)方法調用hi耗時:"+(end-start));
    }
    //反射機制調用hi
    public static void m2() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class<?> cls = Class.forName("com.reflection.People");
        Object o = cls.newInstance();
       Method method = cls.getMethod("hi");
12       
        long start = System.currentTimeMillis();
        for (int i=0;i<900000;i++){
           method.invoke(o);
        }
        long end = System.currentTimeMillis();
        System.out.println("反射機制調用hi耗時:"+(end-start));
    }
}
傳統(tǒng)方法調用hi耗時:4
反射機制調用hi耗時:19

結論:使用反射機制調用方法耗時更長
我們可以進行如下優(yōu)化

反射調用優(yōu)化關閉訪問檢查

1.Method和Field、 Constructor對象都有setAccessible()方法

2.setAccessible作用是啟動和禁用訪問安全檢查的開關

3.參數值為true表示 反射的對象在使用時取消訪問檢查,提高反射的效率。參數值為false則表示反射的對象執(zhí)行訪問檢查

在這里插入圖片描述

代碼第12行加入method.setAccessible(true);//反射的對象在使用時取消訪問檢查,提高反射的效率
代碼效果演示

傳統(tǒng)方法調用hi耗時:3
反射機制調用hi耗時:16

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

相關文章

  • SpringBoot整合EasyCaptcha實現圖形驗證碼功能

    SpringBoot整合EasyCaptcha實現圖形驗證碼功能

    這篇文章主要介紹了SpringBoot整合EasyCaptcha實現圖形驗證碼功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-02-02
  • Java使用組件編寫窗口實現網絡圖片顯示

    Java使用組件編寫窗口實現網絡圖片顯示

    這篇文章主要為大家詳細介紹了Java使用組件編寫窗口實現網絡圖片顯示的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • SpringBoot整合mybatis使用Druid做連接池的方式

    SpringBoot整合mybatis使用Druid做連接池的方式

    這篇文章主要介紹了SpringBoot整合mybatis使用Druid做連接池的方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Java的幾個重要版本_動力節(jié)點Java學院整理

    Java的幾個重要版本_動力節(jié)點Java學院整理

    jdk8 將在2014年3月份發(fā)布,迄今為止,可能是最大更新的java版本,也是令人期待的一個版本,在Java中引入閉包概念對Java程序開發(fā)方法的影響甚至會大于Java5中引入的泛型特征對編程方式帶來的影響
    2017-06-06
  • JAVA實現PDF轉HTML文檔的示例代碼

    JAVA實現PDF轉HTML文檔的示例代碼

    本文是基于PDF文檔轉PNG圖片,然后進行圖片拼接,拼接后的圖片轉為base64字符串,然后拼接html文檔寫入html文件實現PDF文檔轉HTML文檔,感興趣的可以了解一下
    2021-05-05
  • Springboot線程池并發(fā)處理數據優(yōu)化方式

    Springboot線程池并發(fā)處理數據優(yōu)化方式

    這篇文章主要介紹了Springboot線程池并發(fā)處理數據優(yōu)化方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java統(tǒng)計代碼的執(zhí)行時間的N種方法

    Java統(tǒng)計代碼的執(zhí)行時間的N種方法

    在日常開發(fā)中經常需要測試一些代碼的執(zhí)行時間,但又不想使用向 JMH(Java?Microbenchmark Harness,Java 微基準測試套件)這么重的測試框架,所以本文就匯總了一些 Java 中比較常用的執(zhí)行時間統(tǒng)計方法,總共包含以下 6 種,需要的朋友可以參考下
    2022-08-08
  • 關于springboot中對sqlSessionFactoryBean的自定義

    關于springboot中對sqlSessionFactoryBean的自定義

    這篇文章主要介紹了springboot中對sqlSessionFactoryBean的自定義方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • eclipse/IDEA配置javafx項目步驟(圖文教程)

    eclipse/IDEA配置javafx項目步驟(圖文教程)

    這篇文章主要介紹了eclipse/IDEA配置javafx項目步驟(圖文教程),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03
  • Java實現AWT四大事件的詳細過程

    Java實現AWT四大事件的詳細過程

    AWT的事件處理是一種委派式事件處理方式:普通組件(事件源)將整個事件處理委托給特定的對象(事件監(jiān)聽器);當該事件源發(fā)生指定的事件時,就通知所委托的事件監(jiān)聽器,由事件監(jiān)聽器來處理這個事件
    2022-04-04

最新評論

泽库县| 白河县| 浏阳市| 岳西县| 武威市| 青龙| 九台市| 常山县| 登封市| 东乌珠穆沁旗| 漯河市| 紫阳县| 道孚县| 汶上县| 泰宁县| 白水县| 淮安市| 兖州市| 扎赉特旗| 新津县| 新巴尔虎右旗| 卢湾区| 新蔡县| 千阳县| 密山市| 藁城市| 正宁县| 深水埗区| 靖江市| 江华| 蕉岭县| 漯河市| 融水| 湖州市| 塔城市| 中宁县| 海南省| 玛纳斯县| 濮阳县| 绥江县| 望奎县|