午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

java反射基礎(chǔ)知識(shí)總結(jié)

 yespon 2017-06-08

反射定義

JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性。
欲用反射,必先得字節(jié)碼(.class文件對(duì)象)。

先來看看java反射的三個(gè)階段:

Created with Rapha?l 2.1.0源文件階段源文件階段字節(jié)碼階段字節(jié)碼階段創(chuàng)建對(duì)象階段創(chuàng)建對(duì)象階段String.java文件javac命令編譯Class c = Class.forName('java.lang.String');java命令運(yùn)行Class c = String.class;String s = new String();Class c = s.getClass();

每一個(gè)階段我們都有對(duì)應(yīng)的手段得到字節(jié)碼文件對(duì)象,得到對(duì)應(yīng)的字節(jié)碼文件對(duì)象只是我們反射的第一步,我們真正想做的是改變成員變量的屬性值或者是調(diào)用類中的方法。
要想改變屬性或者方法必須得有對(duì)象可行,下面先介紹如何通過反射創(chuàng)建對(duì)象:

反射創(chuàng)建對(duì)象

Class c = String.class; String s = (String) c.newInstance();

一個(gè)字節(jié)碼文件對(duì)象調(diào)用該方法可以創(chuàng)建其實(shí)例對(duì)象,注意此種創(chuàng)建對(duì)象方式只能局限于非私有空參構(gòu)造方法(沒有空參構(gòu)造或者空參構(gòu)造是私有的不能通過此種方法創(chuàng)建對(duì)象)。

Constructor<T> getConstructor(Class<?>... parameterTypes)//根據(jù)指定構(gòu)造參數(shù)類型得到對(duì)應(yīng)的Constructor對(duì)象 Constructor<?>[] getConstructors()//得到包含該類所有public構(gòu)造方法Constructor對(duì)象的數(shù)組

上面的一組方法可以得到public權(quán)限修飾的構(gòu)造方法

Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) Constructor<?>[] getDeclaredConstructors()

在Class類中有一類方法是以getDeclared…開頭的,這一類方法可以得到類中私有的構(gòu)造、屬性和方法。
為了便于舉例說明,這里我們創(chuàng)建一個(gè)自定義的測(cè)試類:

package com.qj.reflect; public class ReflectBean { private ReflectBean() { super();//私有構(gòu)造 } public void print(String s) { System.out.println(s); } }

該類私有了構(gòu)造方法,下面通過反射創(chuàng)建對(duì)象并調(diào)用該類中的方法:

public static void testConstructor() throws Exception { Class c = Class.forName('com.qj.reflect.ReflectBean'); Constructor dc = c.getDeclaredConstructor();//得到私有構(gòu)造 dc.setAccessible(true);// 解除私有權(quán)限 ReflectBean rb = (ReflectBean) dc.newInstance();//創(chuàng)建對(duì)象 rb.print('反射創(chuàng)建對(duì)象調(diào)用方法'); }

反射修改屬性值

與獲取字節(jié)碼對(duì)象的構(gòu)造方法類似,獲取成員屬性Class類中也有對(duì)應(yīng)的API:

Field getField(String name)//根據(jù)屬性名稱獲取Field對(duì)象,僅限public Field[] getFields()//獲取該類所有的public屬性 Field getDeclaredField(String name)//根據(jù)屬性名稱獲取Field對(duì)象,private屬性也可獲取 Field[] getDeclaredFields()//獲取該類所有的屬性

為了便于演示我們?cè)赗eflectBean類中添加一個(gè)屬性flag

private boolean flag = true;

反射修改屬性值:

public static void testField() throws Exception { Class c = Class.forName('com.qj.reflect.ReflectBean'); Constructor dc = c.getDeclaredConstructor();// 得到私有構(gòu)造 dc.setAccessible(true);// 解除私有權(quán)限 ReflectBean rb = (ReflectBean) dc.newInstance();// 創(chuàng)建對(duì)象 Field flag = c.getDeclaredField('flag');//通過屬性flag得到對(duì)應(yīng)的Field對(duì)象 flag.setAccessible(true);// 解除私有權(quán)限 flag.setBoolean(rb, false);//修改屬性值 }

Field類中修改屬性值A(chǔ)PI:

set(Object obj, Object value) setBoolean(Object obj, boolean z) setByte(Object obj, byte b) setChar(Object obj, char c) setDouble(Object obj, double d) setFloat(Object obj, float f) setInt(Object obj, int i) setLong(Object obj, long l) setShort(Object obj, short s)

反射調(diào)用方法

在開發(fā)中經(jīng)常遇到有某個(gè)類的對(duì)象但是方法是私有的,眼巴巴地看著不能調(diào)用,反射的強(qiáng)大之處就是能夠讓你為所欲為!

Method getMethod(String name, Class<?>... parameterTypes) Method[] getMethods() Method getDeclaredMethod(String name, Class<?>... parameterTypes) Method[] getDeclaredMethods()

結(jié)合之前對(duì)于構(gòu)造方法和屬性的獲取,Class類中對(duì)方法對(duì)象的獲取就很容易理解了。
為了演示反射調(diào)用方法,我們?cè)赗eflectBean中添加一個(gè)私有的方法

private void secret() { System.out.println('私有方法被調(diào)用了!'); }

利用反射調(diào)用私有方法:

public static void testMethod() throws Exception{ Class c = Class.forName('com.qj.reflect.ReflectBean'); Constructor dc = c.getDeclaredConstructor();// 得到私有構(gòu)造 dc.setAccessible(true);// 解除私有權(quán)限 ReflectBean rb = (ReflectBean) dc.newInstance();// 創(chuàng)建對(duì)象 Method dm = c.getDeclaredMethod('secret');//根據(jù)方法名稱獲取Method對(duì)象 dm.setAccessible(true);// 解除私有權(quán)限 dm.invoke(rb);//調(diào)用方法 }

我們向ReflectBean測(cè)試類中添加一個(gè)有參的私有方法:

private void secret(String s) { System.out.println('有參私有方法被調(diào)用了! s : ' s); }

反射調(diào)用有參私有方法:

//Class c , ReflectBean rb 生成步驟略 Method dm = c.getDeclaredMethod('secret', String.class);// 根據(jù)方法名稱及方法參數(shù)類型獲取Method對(duì)象 dm.setAccessible(true);// 解除私有權(quán)限 dm.invoke(rb, '方法參數(shù)內(nèi)容');// 調(diào)用方法

眾所周知,我們利用反射無非是為了改變對(duì)象的屬性或者調(diào)用對(duì)象的方法,下面總結(jié)一個(gè)反射的工具類,讓我們使用反射易如反掌!

反射工具類

package com.qj.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; //反射工具類 public class ReflectUtil { private ReflectUtil() { super(); } /** * 根據(jù)全類名得到一個(gè)該類的對(duì)象(僅限非私有空參構(gòu)造) * * @param className 全類名(形如com.qj.reflect.ReflectBean) * @return 該類的實(shí)例 * @throws InstantiationException * @throws IllegalAccessException * @throws ClassNotFoundException */ public static Object newInstance(String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException { Class c = Class.forName(className); Object o = c.newInstance(); return o; } /** * 根據(jù)全類名以及構(gòu)造方法參數(shù)得到一個(gè)該類的對(duì)象 * * @param className 全類名(形如com.qj.reflect.ReflectBean) * @param args 構(gòu)造方法參數(shù)(可變參數(shù)) * @return 該類的實(shí)例 * @throws ClassNotFoundException * @throws NoSuchMethodException * @throws SecurityException * @throws InstantiationException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws InvocationTargetException */ public static Object createInstance(String className, Object... args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Class c = Class.forName(className); Constructor dc = null; int length = args.length; if (args != null && length > 0) {//有參構(gòu)造 Class[] type = new Class[length]; for (int i = 0; i < length; i ) { type[i] = args[i].getClass(); } dc = c.getDeclaredConstructor(type); dc.setAccessible(true); return dc.newInstance(args); } dc = c.getDeclaredConstructor();//無參構(gòu)造 dc.setAccessible(true); return dc.newInstance(); } /** * 根據(jù)傳過來的對(duì)象以及對(duì)象的屬性名稱更改屬性值 * * @param obj 該類的實(shí)例 * @param fieldName 該類的屬性名稱 * @param value 要更改的屬性值 * @throws NoSuchFieldException * @throws SecurityException * @throws IllegalArgumentException * @throws IllegalAccessException */ public static void modfyField(Object obj, String fieldName, Object value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { Class c = obj.getClass(); Field field = c.getDeclaredField(fieldName); field.setAccessible(true); field.set(obj, value); } /** * 根據(jù)傳過來的對(duì)象以及對(duì)象的方法名稱調(diào)用該方法 * * @param obj 該類的實(shí)例 * @param methodName 要調(diào)用的方法 * @param args 方法的參數(shù)(可變參數(shù)) * @throws NoSuchMethodException * @throws SecurityException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws InvocationTargetException */ public static void invokeMethod(Object obj, String methodName, Object... args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Class c = obj.getClass(); Method method = null; if (args != null && args.length > 0) {// 有參方法 Class[] type = new Class[args.length]; for (int i = 0; i < type.length; i ) { type[i] = args[i].getClass(); } method = c.getDeclaredMethod(methodName, type); } else {// 空參方法 method = c.getDeclaredMethod(methodName); } method.setAccessible(true); method.invoke(obj, args); } }

有了這個(gè)工具類我們用反射就很easy了:

ReflectBean obj = (ReflectBean) ReflectUtil .createInstance('com.qj.reflect.ReflectBean');//創(chuàng)建對(duì)象 ReflectUtil.modfyField(obj, 'flag', false);// 修改flag屬性值 ReflectUtil.invokeMethod(obj, 'secret');// 調(diào)用secret空參構(gòu)造 ReflectUtil.invokeMethod(obj, 'secret', '太帥了');// 調(diào)用secret有參構(gòu)造

通過使用反射工具類大大減少了代碼量,一句代碼解決一個(gè)問題,清晰明朗。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多