JVM05 JVM是如何實現(xiàn)反射的?

什么是Java的反射機制?
java的反射機制是在運行狀態(tài)中,對于任意一個類(Class)都能知道他的屬性(Field)和方法(Method),對于任意一個對象都能夠調(diào)用它的方法和屬性;這種動態(tài)獲取信息以及動態(tài)調(diào)用對象方法的功能稱為java語言的反射機制。它允許正在運行的java程序觀測甚至是修改程序的動態(tài)行為。

反射的實現(xiàn)方式有哪些?
1、通過Class.forName()方法加載字符串

Class<?> clazz = Class.forName("java.lang.String")

2、通過類名調(diào)用class屬性得到該類的Class對象

 Class<?> clazz = String.class

3、調(diào)用實例的getClass()方法

 Class<?> clazz = date.getClass()

4、如果是基本類型的包裝類,則可以通過調(diào)用包裝類的Type屬性來獲得該包裝類的Class對象

反射調(diào)用是怎么實現(xiàn)的?
查閱 Method.invoke 的源代碼發(fā)現(xiàn),它實際上委派給 MethodAccessor 來處理。

public final class Method extends Executable {
  ...
  public Object invoke(Object obj, Object... args) throws ... {
    ... // 權限檢查
    MethodAccessor ma = methodAccessor;
    if (ma == null) {
      ma = acquireMethodAccessor();
    }
    return ma.invoke(obj, args);
  }
}

MethodAccessor 是一個接口,它有兩個實現(xiàn):一個通過本地方法來實現(xiàn)反射調(diào)用,另一個使用了委派模式(委派實現(xiàn))。
在默認情況下,方法的反射調(diào)用為委派實現(xiàn),委派給本地實現(xiàn)來進行方法調(diào)用。在調(diào)用超過 15 次之后,委派實現(xiàn)便會將委派對象切換至動態(tài)實現(xiàn)。這個動態(tài)實現(xiàn)的字節(jié)碼是自動生成的,它將直接使用 invoke 指令來調(diào)用目標方法。

反射調(diào)用帶來哪些性能開銷?
1、接口的通用性,java的invoke方法是傳object和object[]數(shù)組的?;緟?shù)類型需要裝箱和拆箱,產(chǎn)生大量額外的對象和內(nèi)存開銷,頻繁促發(fā)GC。
2、編譯器難以對動態(tài)調(diào)用的代碼提前做優(yōu)化比如方法內(nèi)聯(lián)。
3、反射需要按名檢索類和方法,有一定的時間開銷。

反射在java中的應用有哪些?
1、java集成開發(fā)環(huán)境,每當我們敲入點號時,IDE便會根據(jù)點號前的內(nèi)容,動態(tài)展示可以訪問的字段和方法。
2、java調(diào)試器,它能夠在調(diào)試過程中枚舉某一對象所有字段的值。
3、web開發(fā)中,我們經(jīng)常接觸到各種配置的通用框架。為保證框架的可擴展性,他往往借助java的反射機制。例如Spring框架的依賴反轉(zhuǎn)(IOC)便是依賴于反射機制。
4、AOP攔截獲取方法信息。典型的例子:Spring緩存@Cacheable的key生成策略

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容