安利一个优雅的Java反射工具
2019-05-09 本文已影响0人
风云不羁
Java开发中或多或少的会用到反射的方式,通常的反射方式调用如下:
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();
}
}
每一次的反射调用都让人觉得代码有很多冗余的地方,我们总是希望调用的代码显得优雅而简洁。
下面就让我们来欣赏一下优雅的方式:
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
这个工具的封装的功能基本覆盖反射调用所有方式,感兴趣的看官可以去看一下源码及使用方式。另外该库还支持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());
扩展
如果项目中同一种反射的调用次数比较频繁的情况下,可以做缓存处理,避免每次都直接反射属性或者方法:
//缓存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<>();
}