一個事半功倍的 Java 反射庫

在Java和Android中,我們常常會使用反射來達到一些兼容的目的。Java原生提供的反射很是麻煩,使用起來很是不方便。比如我們想要調UserManager的靜態(tài)方法get,使用原生的實現(xiàn)如下

try {

final Method m = UserManager.class.getMethod("get", Context.class);

m.setAccessible(true);

m.invoke(null, this);

} catch (NoSuchMethodException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (InvocationTargetException e) {

e.printStackTrace();

}

實現(xiàn)起來好不麻煩。這其中

需要確定方法名和參數(shù)來獲取對應的Method對象

設置Method對象的assessible為true

調用invoke方法,并且傳入對應的參數(shù)

捕獲其中可能拋出來的一連串異常

那么反射能簡單點么,當然,而且還會簡單很多。

這就是本文想要介紹的,jOOR(Java Object Oriented Reflection),它是一個對java.lang.reflect包的簡單封裝,使得我們使用起來更加直接和方便。

使用jOOR,上面的代碼可以縮短成一行。

Reflect.on(UserManager.class).call("get", getApplicationContext());

依賴

jOOR沒有依賴。

使用jOOR只需要將這兩個文件,加入工程即可。

API介紹

Reflect

Reflect.on 包裹一個類或者對象,表示在這個類或對象上進行反射,類的值可以使Class,也可以是完整的類名(包含包名信息)

Reflect.create 用來調用之前的類的構造方法,有兩種重載,一種有參數(shù),一種無參數(shù)

Reflect.call 方法調用,傳入方法名和參數(shù),如有返回值還需要調用get

Reflect.get 獲?。╢ield和method返回)值相關,會進行類型轉換,常與call和field組合使用

Reflect.field 獲取屬性值相關,需要調用get獲取該值

Reflect.set 設置屬性相關。

ReflectException

引入ReflectException避免了我們?nèi)atch過多的異常,也減少了縱向代碼量,使得代碼簡潔不少。ReflectException拋出,可能是發(fā)生了以下異常。

ClassNotFoundException

IllegalAccessException

IllegalArgumentException

InstantiationException

InvocationTargetException

NoSuchMethodException

NoSuchFieldException

SecurityException

除此之外,ReflectException屬于unchecked 異常,語法上不需要顯式進行捕獲,但是也需要根據(jù)實際情況,斟酌是否進行顯式捕獲該異常。

使用示例

創(chuàng)建實例

String string = Reflect.on(String.class).create("Hello World").get();

訪問屬性(public,protected,package,private均可)

1

char pathSeparatorChar = Reflect.on(File.class).create("/sdcard/droidyue.com").field("pathSeparatorChar").get();

修改屬性(final屬性也可以修改)

1

String setValue = Reflect.on(File.class).create("/sdcard/drodiyue.com").set("path", "fakepath").get("path");

調用方法(public,protected,package,private均可)

ArrayList arrayList = new ArrayList();

arrayList.add("Hello");

arrayList.add("World");

int value = Reflect.on(arrayList).call("hugeCapacity", 12).get();

實現(xiàn)原理

Reflect實際是對原生java reflect進行封裝,屏蔽了無關細節(jié)。

以fields方法為例,其內(nèi)部實現(xiàn)可以看出是調用了java原生提供的反射相關的代碼。

public Map fields() {Mapresult = new LinkedHashMap();Class type = type(); do { for (Field field : type.getDeclaredFields()) { if (!isClass ^ Modifier.isStatic(field.getModifiers())) { String name = field.getName(); if (!result.containsKey(name)) result.put(name, field(name)); } } type = type.getSuperclass(); } while (type != null); return result;}

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

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

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