Object result = method.invoke(bean);
反射(Reflection)是Java 程序開發(fā)語言的特征之一潘拱,它允許運行中的 Java 程序獲取自身的信息疹鳄,并且可以操作類或?qū)ο蟮膬?nèi)部屬性。
程序中對象的類型都是在編譯期就確定下來的芦岂,而Java反射機制可以動態(tài)地創(chuàng)建對象并調(diào)用其屬性瘪弓。但在有的時候并沒有進行編譯期就要直接使用,比如class.forName方法禽最。
反射的核心是JVM在運行時才動態(tài)加載類或調(diào)用方法/訪問屬性腺怯,它不需要事先(寫代碼的時候或編譯期)知道對象的類型。
Java反射框架主要提供以下功能:
1.在運行時動態(tài)進行類加載弛随;
2.在運行時創(chuàng)建一個對象瓢喉;
3.在運行時獲取類(對象)的任意成員變量和方法
4.在運行時調(diào)用任意一個對象的方法(通過反射甚至可以調(diào)用private方法);
重點是運行時而不是編譯時
當我們在使用IDE(如Eclipse舀透,IDEA)時栓票,當我們輸入一個對象或類并想調(diào)用它的屬性或方法時,一按點號愕够,編譯器就會自動列出它的屬性或方法走贪,這里就會用到反射。
反射最重要的用途就是開發(fā)各種通用框架惑芭。
很多框架(比如Spring)都是配置化的(比如通過XML文件配置JavaBean,Action之類的)坠狡,為了保證框架的通用性,它們可能需要根據(jù)配置文件加載不同的對象或類遂跟,調(diào)用不同的方法逃沿,這個時候就必須用到反射——運行時動態(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建立了一種映射關系幻锁,當View層發(fā)出請求時凯亮,請求會被StrutsPrepareAndExecuteFilter攔截,然后StrutsPrepareAndExecuteFilter會去動態(tài)地創(chuàng)建Action實例哄尔。
struts與spring mvc的區(qū)別是struts是原型的假消,springmvc是單列的。
獲得Class對象的三種方法:
(1)使用Class類的forName靜態(tài)方法
(2)直接獲取某一個對象的class岭接,比如 a.class
(3)調(diào)用某個對象的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對象對應類的實例
(2)先通過Class對象獲取指定的Constructor對象富拗,再調(diào)用Constructor對象的newInstance()方法來創(chuàng)建實例臼予。這種方法可以用指定的構(gòu)造器構(gòu)造類的實例:
//獲取String所對應的Class對象
Class<?> c = String.class;
//獲取String類帶一個String參數(shù)的構(gòu)造器
Constructor constructor = c.getConstructor(String.class);
//根據(jù)構(gòu)造器創(chuàng)建實例
Object obj = constructor.newInstance("23333");
System.out.println(obj);
獲取某個Class對象的方法集合,主要有以下幾個方法:
getDeclaredMethods()方法返回類或接口聲明的所有方法啃沪,包括公共粘拾、保護谅阿、默認(包)訪問和私有方法半哟,但不包括繼承的方法签餐。
public Method[] getDeclaredMethods() throws SecurityException
getMethods()方法返回某個類的所有公用(public)方法,包括其繼承類的公用方法戒良。
public Method[] getMethods() throws SecurityException
getMethod方法返回一個特定的方法冠摄,其中第一個參數(shù)為方法名稱糯崎,后面的參數(shù)為方法的參數(shù)對應Class的對象
public Method getMethod(String name, Class<?>... parameterTypes)
獲取類的成員變量(字段)信息,直接使用較少河泳,因為變量一般為私有的。
getFiled: 訪問公有的成員變量
getDeclaredField:所有已聲明的成員變量薄霜。但不能得到其父類的成員變量
getFileds和getDeclaredFields用法同上(參照Method)
當我們從類中獲取了一個方法后纸兔,我們就可以用invoke()方法來調(diào)用這個方法惰瓜。invoke方法的原型為:
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
反射調(diào)用方法時可以忽略權(quán)限檢查汉矿,因此可能會破壞封裝性而導致安全問題。