Java開發(fā)中或多或少的會用到反射的方式,通常的反射方式調(diào)用如下:
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
private void setName(String name) {
this.name = name;
}
}
public String getPersonName(Person person) {
Class pClass = person.getClass();
try {
Field nameField = pClass.getDeclaredField("name");
return (String) nameField.get(person);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
public void setPersonName(Person person, String name) {
Class pClass = person.getClass();
try {
Method setName;
setName = pClass.getDeclaredMethod("setName", pClass, String.class);
setName.setAccessible(true);
setName.invoke(person, name);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
每一次的反射調(diào)用都讓人覺得代碼有很多冗余的地方蚁堤,我們總是希望調(diào)用的代碼顯得優(yōu)雅而簡潔。
下面就讓我們來欣賞一下優(yōu)雅的方式:
public String getName(Person person) {
try {
return Reflect.on(person).get("name");
} catch (Reflect.ReflectException e) {
return null;
}
}
public void setName(Person person, String name) {
try {
Reflect.on(person).call("setName", name);
} catch (Reflect.ReflectException e) {
e.printStackTrace();
}
}
該反射工具的源碼地址 jOOR
這個工具的封裝的功能基本覆蓋反射調(diào)用所有方式杖虾,感興趣的看官可以去看一下源碼及使用方式条辟。另外該庫還支持Java代碼的運行時編譯:
Supplier<String> supplier = Reflect.compile(
"com.example.HelloWorld",
"package com.example;\n" +
"class HelloWorld implements java.util.function.Supplier<String> {\n" +
" public String get() {\n" +
" return \"Hello World!\";\n" +
" }\n" +
"}\n").create().get();
// Prints "Hello World!"
System.out.println(supplier.get());
擴展
如果項目中同一種反射的調(diào)用次數(shù)比較頻繁的情況下,可以做緩存處理胳施,避免每次都直接反射屬性或者方法:
//緩存ClassName對應的Class
private static ConcurrentHashMap<String, Class> classCache;
//緩存屬性值
private static ConcurrentHashMap<String, Field> fieldCache;
//緩存方法
private static ConcurrentHashMap<String, Method> methodCache;
static {
classCache = new ConcurrentHashMap<>();
fieldCache = new ConcurrentHashMap<>();
methodCache = new ConcurrentHashMap<>();
}