invoke過程

Object result = method.invoke(bean);

反射(Reflection)是Java 程序開發(fā)語言的特征之一,它允許運(yùn)行中的 Java 程序獲取自身的信息,并且可以操作類或?qū)ο蟮膬?nèi)部屬性。

程序中對象的類型都是在編譯期就確定下來的,而Java反射機(jī)制可以動態(tài)地創(chuàng)建對象并調(diào)用其屬性。但在有的時(shí)候并沒有進(jìn)行編譯期就要直接使用,比如class.forName方法。

反射的核心是JVM在運(yùn)行時(shí)才動態(tài)加載類或調(diào)用方法/訪問屬性,它不需要事先(寫代碼的時(shí)候或編譯期)知道對象的類型。

Java反射框架主要提供以下功能:
1.在運(yùn)行時(shí)動態(tài)進(jìn)行類加載;
2.在運(yùn)行時(shí)創(chuàng)建一個(gè)對象;
3.在運(yùn)行時(shí)獲取類(對象)的任意成員變量和方法
4.在運(yùn)行時(shí)調(diào)用任意一個(gè)對象的方法(通過反射甚至可以調(diào)用private方法);
重點(diǎn)是運(yùn)行時(shí)而不是編譯時(shí)

當(dāng)我們在使用IDE(如Eclipse,IDEA)時(shí),當(dāng)我們輸入一個(gè)對象或類并想調(diào)用它的屬性或方法時(shí),一按點(diǎn)號,編譯器就會自動列出它的屬性或方法,這里就會用到反射。

反射最重要的用途就是開發(fā)各種通用框架。
很多框架(比如Spring)都是配置化的(比如通過XML文件配置JavaBean,Action之類的),為了保證框架的通用性,它們可能需要根據(jù)配置文件加載不同的對象或類,調(diào)用不同的方法,這個(gè)時(shí)候就必須用到反射——運(yùn)行時(shí)動態(tài)加載需要加載的對象。

<action name="login"   class="org.ScZyhSoft.test.action.SimpleLoginAction"  method="execute">
       <result>index.jsp</result>
       <result name="error">login.jsp</result>
 </action>

配置文件與Action建立了一種映射關(guān)系,當(dāng)View層發(fā)出請求時(shí),請求會被StrutsPrepareAndExecuteFilter攔截,然后StrutsPrepareAndExecuteFilter會去動態(tài)地創(chuàng)建Action實(shí)例。
struts與spring mvc的區(qū)別是struts是原型的,springmvc是單列的。

獲得Class對象的三種方法:
(1)使用Class類的forName靜態(tài)方法
(2)直接獲取某一個(gè)對象的class,比如 a.class
(3)調(diào)用某個(gè)對象的getClass()方法,比如 a.getClass()

instanceof 和 isInstance區(qū)別:

obj instanceof Type
class.isInstance(obj)

        System.out.println("ok" instanceof  String);
        System.out.println("ok".getClass().isInstance(""));

通過反射來生成對象主要有兩種方式:
(1)使用Class對象的newInstance()方法來創(chuàng)建Class對象對應(yīng)類的實(shí)例
(2)先通過Class對象獲取指定的Constructor對象,再調(diào)用Constructor對象的newInstance()方法來創(chuàng)建實(shí)例。這種方法可以用指定的構(gòu)造器構(gòu)造類的實(shí)例:

      //獲取String所對應(yīng)的Class對象
      Class<?> c = String.class;
      //獲取String類帶一個(gè)String參數(shù)的構(gòu)造器
      Constructor constructor = c.getConstructor(String.class);
      //根據(jù)構(gòu)造器創(chuàng)建實(shí)例
      Object obj = constructor.newInstance("23333");
      System.out.println(obj);

獲取某個(gè)Class對象的方法集合,主要有以下幾個(gè)方法:
getDeclaredMethods()方法返回類或接口聲明的所有方法,包括公共、保護(hù)、默認(rèn)(包)訪問和私有方法,但不包括繼承的方法。

public Method[] getDeclaredMethods() throws SecurityException

getMethods()方法返回某個(gè)類的所有公用(public)方法,包括其繼承類的公用方法。

public Method[] getMethods() throws SecurityException

getMethod方法返回一個(gè)特定的方法,其中第一個(gè)參數(shù)為方法名稱,后面的參數(shù)為方法的參數(shù)對應(yīng)Class的對象

public Method getMethod(String name, Class<?>... parameterTypes)

獲取類的成員變量(字段)信息,直接使用較少,因?yàn)樽兞恳话銥樗接械摹?/p>

getFiled: 訪問公有的成員變量
getDeclaredField:所有已聲明的成員變量。但不能得到其父類的成員變量
getFileds和getDeclaredFields用法同上(參照Method)

當(dāng)我們從類中獲取了一個(gè)方法后,我們就可以用invoke()方法來調(diào)用這個(gè)方法。invoke方法的原型為:

public Object invoke(Object obj, Object... args)
        throws IllegalAccessException, IllegalArgumentException,
           InvocationTargetException

反射調(diào)用方法時(shí)可以忽略權(quán)限檢查,因此可能會破壞封裝性而導(dǎo)致安全問題。

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

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,525評論 19 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,828評論 25 709
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,032評論 0 9
  • 之前搭建了Shipyard,可以對鏡像、容器、Node進(jìn)行管理,但在添加registry時(shí)出錯(cuò)啦。 試錯(cuò)1:剛開始...
    灼灼2015閱讀 4,777評論 3 6
  • 人逢喜事精神爽,古人誠不欺我。最近,蘇沫一直處于亢奮忙碌狀態(tài),就連她先生都不無羨慕地說,做蘇沫的弟弟,真是太幸福了...
    夢宇星月夜閱讀 316評論 0 0

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