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

Java方法反射實(shí)現(xiàn)原理詳解

 更新時(shí)間:2017年10月16日 15:27:58   作者:維C果糖  
這篇文章主要為大家詳細(xì)介紹了Java方法反射的實(shí)現(xiàn)原理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

博主說:Java 反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意方法和屬性;這種動(dòng)態(tài)獲取信息以及動(dòng)態(tài)調(diào)用對(duì)象方法的功能稱為 Java 語言的反射機(jī)制。在本文中,占小狼分析了 Java 反射機(jī)制的實(shí)現(xiàn)原理(源碼),感興趣的同學(xué)可以通過閱讀本文花上幾分鐘了解了解。

正文

kava

方法反射實(shí)例

public class ReflectCase {

  public static void main(String[] args) throws Exception {
    Proxy target = new Proxy();
    Method method = Proxy.class.getDeclaredMethod("run");
    method.invoke(target);
  }

  static class Proxy {
    public void run() {
      System.out.println("run");
    }
  }
}

通過 Java 的反射機(jī)制,可以在運(yùn)行期間調(diào)用對(duì)象的任何方法,如果大量使用這種方式進(jìn)行調(diào)用,會(huì)有性能或內(nèi)存隱患么?為了徹底了解方法的反射機(jī)制,只能從底層代碼入手啦!

Method 獲取

調(diào)用 Class 類的getDeclaredMethod可以獲取指定方法名和參數(shù)的方法對(duì)象 Method。

getDeclaredMethod

getDeclaredMethod

其中privateGetDeclaredMethods方法從緩存或 JVM 中獲取該 Class 中申明的方法列表,searchMethods方法將從返回的方法列表里找到一個(gè)匹配名稱和參數(shù)的方法對(duì)象。

searchMethods

searchMethods

如果找到一個(gè)匹配的 Method,則重新復(fù)制一份返回,即Method.copy()方法。

methodcopy

所次每次調(diào)用getDeclaredMethod方法返回的 Method 對(duì)象其實(shí)都是一個(gè)新的對(duì)象,且新對(duì)象的root屬性都指向原來的 Method 對(duì)象,如果需要頻繁調(diào)用,最好把 Method 對(duì)象緩存起來。

privateGetDeclaredMethods

從緩存或 JVM 中獲取該 Class 中申明的方法列表,實(shí)現(xiàn)如下:

privateGetDeclaredMethods

其中reflectionData()方法實(shí)現(xiàn)如下:

reflectionData

這里有個(gè)比較重要的數(shù)據(jù)結(jié)構(gòu)ReflectionData,用來緩存從 JVM 中讀取類的如下屬性數(shù)據(jù):

JVM

從reflectionData()方法實(shí)現(xiàn)可以看出:reflectionData對(duì)象是SoftReference類型的,說明在內(nèi)存緊張時(shí)可能會(huì)被回收,不過也可以通過-XX:SoftRefLRUPolicyMSPerMB參數(shù)控制回收的時(shí)機(jī),只要發(fā)生GC就會(huì)將其回收,如果reflectionData被回收之后,又執(zhí)行了反射方法,那只能通過newReflectionData方法重新創(chuàng)建一個(gè)這樣的對(duì)象了,newReflectionData方法實(shí)現(xiàn)如下:

newReflectionData

通過unsafe.compareAndSwapObject方法重新設(shè)置reflectionData字段;在privateGetDeclaredMethods方法中,如果通過reflectionData()獲得的ReflectionData對(duì)象不為空,則嘗試從ReflectionData對(duì)象中獲取declaredMethods屬性,如果是第一次,或則被GC回收之后,重新初始化后的類屬性為空,則需要重新到 JVM 中獲取一次,并賦值給ReflectionData,下次調(diào)用就可以使用緩存數(shù)據(jù)了。

Method 調(diào)用

獲取到指定的方法對(duì)象 Method 之后,就可以調(diào)用它的invoke方法了,invoke實(shí)現(xiàn)如下:

invoke

應(yīng)該注意到:這里的MethodAccessor對(duì)象是invoke方法實(shí)現(xiàn)的關(guān)鍵,一開始methodAccessor為空,需要調(diào)用acquireMethodAccessor生成一個(gè)新的MethodAccessor對(duì)象,MethodAccessor本身就是一個(gè)接口,實(shí)現(xiàn)如下:

MethodAccessor

在acquireMethodAccessor方法中,會(huì)通過ReflectionFactory類的newMethodAccessor創(chuàng)建一個(gè)實(shí)現(xiàn)了MethodAccessor接口的對(duì)象,實(shí)現(xiàn)如下:

newMethodAccessor

在ReflectionFactory類中,有 2 個(gè)重要的字段:noInflation(默認(rèn)false)和inflationThreshold(默認(rèn)15),在checkInitted方法中可以通過-Dsun.reflect.inflationThreshold=xxx和-Dsun.reflect.noInflation=true對(duì)這兩個(gè)字段重新設(shè)置,而且只會(huì)設(shè)置一次;如果noInflation為false,方法newMethodAccessor都會(huì)返回DelegatingMethodAccessorImpl對(duì)象,DelegatingMethodAccessorImpl的類實(shí)現(xiàn):

DelegatingMethodAccessorImpl

其實(shí),DelegatingMethodAccessorImpl對(duì)象就是一個(gè)代理對(duì)象,負(fù)責(zé)調(diào)用被代理對(duì)象delegate的invoke方法,其中delegate參數(shù)目前是NativeMethodAccessorImpl對(duì)象,所以最終 Method 的invoke方法調(diào)用的是NativeMethodAccessorImpl對(duì)象invoke方法,實(shí)現(xiàn)如下:

這里用到了ReflectionFactory類中的inflationThreshold,當(dāng)delegate調(diào)用了15次invoke方法之后,如果繼續(xù)調(diào)用就通過MethodAccessorGenerator類的generateMethod方法生成MethodAccessorImpl對(duì)象,并設(shè)置為delegate對(duì)象,這樣下次執(zhí)行Method.invoke時(shí),就調(diào)用新建的MethodAccessor對(duì)象的invoke()方法了。這里需要注意的是:generateMethod方法在生成MethodAccessorImpl對(duì)象時(shí),會(huì)在內(nèi)存中生成對(duì)應(yīng)的字節(jié)碼,并調(diào)用ClassDefiner.defineClass創(chuàng)建對(duì)應(yīng)的 Class 對(duì)象,實(shí)現(xiàn)如下:

return

在ClassDefiner.defineClass方法實(shí)現(xiàn)中,每被調(diào)用一次都會(huì)生成一個(gè)DelegatingClassLoader類加載器對(duì)象:

DelegatingClassLoader

這里每次都生成新的類加載器,是為了性能考慮,在某些情況下可以卸載這些生成的類,因?yàn)轭惖男遁d是只有在類加載器可以被回收的情況下才會(huì)被回收的,如果用了原來的類加載器,那可能導(dǎo)致這些新創(chuàng)建的類一直無法被卸載,從其設(shè)計(jì)來看本身就不希望這些類一直存在內(nèi)存里的,在需要的時(shí)候有就行啦!

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java鏈接redis_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java鏈接redis_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了Java鏈接redis,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • Spring Boot的Controller控制層和頁(yè)面

    Spring Boot的Controller控制層和頁(yè)面

    這篇文章主要介紹了Spring Boot的Controller控制層和頁(yè)面,需要的朋友可以參考下
    2017-04-04
  • Java中LinkedList數(shù)據(jù)結(jié)構(gòu)的詳細(xì)介紹

    Java中LinkedList數(shù)據(jù)結(jié)構(gòu)的詳細(xì)介紹

    這篇文章主要介紹了Java中LinkedList,Linked List 是 java.util 包中 Collection 框架的一部分,文中提供了詳細(xì)的代碼說明,需要的朋友可以參考下
    2023-05-05
  • Spring中如何自定義監(jiān)聽器

    Spring中如何自定義監(jiān)聽器

    這篇文章將通過一個(gè)簡(jiǎn)單的自定義的監(jiān)聽器,從源碼的角度分析一下Spring中監(jiān)聽的整個(gè)過程,分析監(jiān)聽的作用,感興趣的小伙伴可以了解一下
    2024-11-11
  • java 類加載機(jī)制和反射詳解及實(shí)例代碼

    java 類加載機(jī)制和反射詳解及實(shí)例代碼

    這篇文章主要介紹了java 類加載機(jī)制和反射詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • springboot實(shí)現(xiàn)異步任務(wù)

    springboot實(shí)現(xiàn)異步任務(wù)

    這篇文章主要為大家詳細(xì)介紹了springboot實(shí)現(xiàn)異步任務(wù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • 詳解pom.xml中maven profile的激活方式

    詳解pom.xml中maven profile的激活方式

    本文主要介紹了詳解pom.xml中maven profile的激活方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • Java抽象類與接口區(qū)別詳解

    Java抽象類與接口區(qū)別詳解

    這篇文章主要介紹了Java抽象類與接口區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • IDEA高效使用設(shè)置指南

    IDEA高效使用設(shè)置指南

    本文主要為大家介紹了關(guān)于IDEA高效的設(shè)置指南,其中包含必備的一些插件推薦以及主題優(yōu)化還有IDEA源碼的閱讀技巧,干貨滿滿,有需要的朋友可以借鑒參考下
    2022-01-01
  • Java雙色球系統(tǒng)開發(fā)詳解

    Java雙色球系統(tǒng)開發(fā)詳解

    這篇文章主要為大家詳細(xì)介紹了Java雙色球系統(tǒng)的開發(fā),超級(jí)簡(jiǎn)單的邏輯,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09

最新評(píng)論

巴彦县| 绥德县| 丹巴县| 凤凰县| 兴宁市| 仲巴县| 孝感市| 邳州市| 吉首市| 乐亭县| 巢湖市| 漯河市| 迁安市| 巨野县| 宝坻区| 南昌市| 乌鲁木齐县| 新晃| 巴塘县| 巴林左旗| 武汉市| 东台市| 和平县| 溆浦县| 邹城市| 红河县| 平原县| 汉阴县| 沐川县| 柯坪县| 德州市| 南江县| 德保县| 灵宝市| 原阳县| 万山特区| 乌兰察布市| 琼海市| 区。| 阿尔山市| 沿河|