Java是一門安全性很高的語言扇售,在編譯時(shí)會(huì)對(duì)語法進(jìn)行檢查,有著嚴(yán)格的語法要求嚣艇,正因?yàn)槿绱顺斜撵`活性略顯不足。Java發(fā)射機(jī)制很好的補(bǔ)充了這個(gè)短板食零。
public class ClassOne { private final int param = 0; public final int param2 = 1; public int getParam(){ return param; } private void print(int i){ System.out.println(i); } }
首先我們創(chuàng)建一個(gè)ClassOne類困乒,一會(huì)我們就用反射來獲取這個(gè)類的信息。
try { Class C = Class.forName("ClassOne"); Object c = C.newInstance(); System.out.println(c.getClass()); } catch (Exception e){ e.printStackTrace(); }
這是一段簡(jiǎn)單的運(yùn)用反射的代碼贰谣,forName()方法通過類名獲取到這個(gè)類ClassOne(當(dāng)然這個(gè)類你要自己建啦)娜搂,newInstance()方法可以調(diào)用類C的無參構(gòu)造方法迁霎,創(chuàng)建一個(gè)C類的對(duì)象。由于反射不一定能夠獲得這個(gè)類百宇,所以要用try catch包含考廉。
Field[] field = C.getDeclaredFields();
獲取類的參數(shù),通過getDeclaredFields()方法携御,這個(gè)方法會(huì)返回一個(gè)數(shù)組昌粤,不僅包括那些public成員變量,還包括private的成員變量啄刹。
這里我們通過field.getModifiers()可以獲得一個(gè)int型的值涮坐,它代表著這個(gè)成員變量的修飾符。
Modifier.toString(field[0].getModifiers())
可以把這個(gè)int型轉(zhuǎn)換成對(duì)應(yīng)的字符串誓军,得到的結(jié)果是public static這樣袱讹。
反射中調(diào)用方法
反射可以獲得類的相關(guān)信息,不過更重要的是使用類中的方法昵时。
在Java語言中捷雕,一切皆對(duì)象,甚至類也是對(duì)象壹甥,是Class類的對(duì)象非区,類的方法也是對(duì)象,是Method的對(duì)象盹廷。所以我們可以通過這么一行代碼來獲取所有的方法。
Method[] m = c.getMethods();
當(dāng)然我們也可以獲取特定的方法久橙,比如ClassOne里的print方法俄占。
確定一個(gè)方法需要兩點(diǎn)
- 方法名
- 參數(shù)
Method method = c.getDeclaredMethod("print", int.class);
然后我們通過invoke()方法來調(diào)用這個(gè)方法。
method.invoke(classOne,3);
這樣打印出來的是3淆衷,也就是我們調(diào)用成功了缸榄。
值得一提的一點(diǎn):
反射是跳過編譯,在運(yùn)行時(shí)才進(jìn)行的祝拯,所以有一些特殊的功能甚带。比如跳過泛型,因?yàn)榉盒褪莏ava在編譯時(shí)為了防止我們出錯(cuò)而出現(xiàn)的產(chǎn)物佳头。比如
ArrayList<String> list
要求list里的元素都是String類型的鹰贵,不過我們可以通過反射來往里添加其他類型的元素。
ArrayList<String> list = new ArrayList<String>(); list.add("hello"); Class c = list.getClass(); Methodmethod=c.getMethod("add",Object.class); method.invoke(list,100); System.out.println(list.toString());
最后輸出的結(jié)果是[hello, 100]