Java反射获取父类中的元素
我们知道,可以通过getDeclaredField和getField方法可以反射获取class中的元素,他们的区别在于getField只能访问公有变量,而getDeclaredField则可以访问定义的所有变量,包括protected修饰和private修饰的变量。
// 1.getDeclaredField方法调用searchFields方法
Field field = searchFields(privateGetDeclaredFields(false), name);
// 2.getField方法剪接调用searchFields方法
if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {
return res;
}
不过,若要访问父类中的元素,通过getDeclaredField和getField方法就会抛出NoSuchFieldException异常了。也就是说,无法直接用java.lang.Class中的方法去访问父类中的元素。Spring中的工具类org.springframework.util.ReflectionUtils提供了findField方法,能够取得父类中的元素。我们看一下其中的实现:
public static Field findField(Class<?> clazz, String name, Class<?> type) {
Assert.notNull(clazz, "Class must not be null");
Assert.isTrue(name != null || type != null, "Either name or type of the field must be specified");
Class<?> searchType = clazz;
while (!Object.class.equals(searchType) && searchType != null) {
// 这里一次性获取了类中的所有元素
Field[] fields = searchType.getDeclaredFields();
for (Field field : fields) {
if ((name == null || name.equals(field.getName())) && (type == null || type.equals(field.getType()))) {
return field;
}
}
// 获取所有父类,接着遍历父类中的元素。
searchType = searchType.getSuperclass();
}
return null;
}
笔者本希望通过getDeclaredField()方法直接反射获取class中的元素,不过为了获取其父类中的元素使用了工具类ReflectionUtils。我们通过计算getDeclaredField()方法和ReflectionUtils.findField()方法在1秒内获取类中元素的次数来判断两者的性能。
public static void main(String[] args) {
try {
int times = 0;
long startMili = System.currentTimeMillis();
while (true) {
long nowMili = System.currentTimeMillis();
InteBidResultDTO.class.getDeclaredField("balance");
times++;
if (nowMili > startMili + 1000) {
break;
}
}
System.out.println("getDeclaredField方法执行了" + times + "次");
times = 0;
startMili = System.currentTimeMillis();
while (true) {
long nowMili = System.currentTimeMillis();
ReflectionUtils.findField(InteBidResultDTO.class, "balance");
times++;
if (nowMili > startMili + 1000) {
break;
}
}
System.out.println("findField方法执行了" + times + "次");
} catch (SecurityException | NoSuchFieldException e) {
e.printStackTrace();
}
}
运行结果是:
getDeclaredField方法执行了3200996次
findField方法执行了2434921次
由于ReflectionUtils.findField()方法会去查找父类中的元素,性能必然会差一些。如果一个类的父类祖先越多,遍历次数也就越多,上述运行结果的差距也就更加明显。
作者:盖世胖胖
来源链接:https://blog.csdn.net/peerless_hero/article/details/54141623
版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。
2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。