何為反射:Java反射機(jī)制是在運(yùn)行狀態(tài)中,對于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對于任意一個(gè)對象屡穗,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對象的方法的功能稱為java語言的反射機(jī)制忽肛。
這句化很抽象村砂!那我們該如何理解這句話呢?
我們都知道Java所有的類的默認(rèn)繼承Object類屹逛,Object類提供了一個(gè)public final native Class<?> getClass() 的方法础废,也就是說任何一個(gè)對象在程序運(yùn)行期間都能知道他是那個(gè)類的實(shí)例。
不信我們寫段代碼來測試下:
運(yùn)行結(jié)果:
運(yùn)行結(jié)果說明我們確實(shí)可以在程序運(yùn)行期間獲取到該對象是那個(gè)類的實(shí)例罕模。
那我們再來看看Class類又提供了哪些方法:
乍一看好多啊色迂,那我們在平時(shí)的工作中到底該掌握哪些呢?
1手销、public T newInstance()? ?通過此方法可以調(diào)用類的默認(rèn)構(gòu)造器獲取一個(gè)類的實(shí)例
2歇僧、public Constructor?getConstructor(Class... parameterTypes) 通過此方法可以獲取類的一個(gè)構(gòu)造器
3、public Field[] getDeclaredFields() 通過此方法可以獲取到類中的所用屬性
4锋拖、public Method getMethod(String name, Class... parameterTypes) 根據(jù)方法名和參數(shù)類型來獲取方法诈悍。(為啥還需要參數(shù)類型,因?yàn)镴ava用方法重載機(jī)制)
5兽埃、public Method[] getMethods() 獲取類的所有方法
6侥钳、public native boolean isInstance(Object obj)? ?判斷對象是不是類的實(shí)例
7、public native boolean isInterface() 判斷類是不是接口類
8柄错、public native boolean isArray(); 判斷類是不是數(shù)組
還有很多方法我們就不一一介紹了舷夺,上面的這些方法只是我們在運(yùn)用反射時(shí)比較常用的。如果你有興趣了解可自行到官網(wǎng)查閱售貌。
下面重點(diǎn)來了给猾,我們?nèi)绾问褂眠@些方法呢。比如現(xiàn)在要讓你做一個(gè)業(yè)務(wù)場景颂跨,對一個(gè)方法傳過來的對象的所有屬性值做非空校驗(yàn)敢伸。但是需要保證方法的通用性。那我們就可以這么寫:
public static boolean checkProperty(Object object)throws Exception {
????//獲取所有屬性
? ? Field[] fields = object.getClass().getDeclaredFields();
? ? for (Field field : fields) {
????????if (field.get(object) !=null)return false;
? ? }
????return true;
}
這樣我們在不必知道一個(gè)需要檢驗(yàn)的類有哪些屬性恒削,只要他存在我們就能校驗(yàn).我門也不需要管它的這個(gè)屬性到底提供沒提供訪問方法池颈。是不是很強(qiáng)大尾序。
再比如說,我要寫一個(gè)Excel的導(dǎo)入功能躯砰。正常程序員都是對于不同的表格寫不同的方法來與之對應(yīng)的解析每币,那么能不能所有的解析操作用一個(gè)方法就能解決呢。那么答案是肯定的琢歇。
public static <T>? List<T>?getExcelData(Class<T> clazz, Workbook workbook) throws Exception {
????List list =new ArrayList<>();
? ? Field[] fields = clazz.getClass().getDeclaredFields();
? ? Sheet sheet = workbook.getSheet("要解析的表格");
? ? for (int i =0; i < sheet.getLastRowNum(); i++) {
? ? ? ? T object = clazz.newInstance();
? ? ? ? for (int j =0; j < fields.length; j++) {
????????fields[j].set(object, sheet.getRow(i).getCell(j));
? ? ? ? }
????????list.add(object);
? ? }
????return list;
}
上面的方法只是一個(gè)演示版本兰怠,很多細(xì)節(jié)都沒有考慮。但是你能感覺到反射所帶來的對一些規(guī)則性很強(qiáng)的業(yè)務(wù)可以做到很簡潔的實(shí)現(xiàn)矿微。我們不必對這些功能大致相同的東西都要費(fèi)心費(fèi)力的反復(fù)復(fù)制痕慢、粘貼尚揣,修改涌矢。大大提升了我們的工作效率。