问题发现:
在走读业务代码过程中发现存在如下情况,大致可以推测,代码原本是希望通过判断属性声明类型来作不同的业务处理,但使用的是先getGenericType().toString()获取属性字符串,再根据字符删除判断
String type = field.getGenericType().toString();//1. 先获取属性类型
if ("class java.lang.Integer".equals(type)){//2. 再根据类型字符串进行判断
Object o = field.get(t);
if (null != o){
//业务代码;
}
}
else if (type.contains("java.util.List")){
//业务代码;
}
这样做存在两个问题:
- 如果属性使用的int基本类型进行声明,则代码对基本类型的判断就是错误的,如int属性的getGenericType().toString()获得的就是‘int’
- 这样相当于隐式的要求基本类型(int,flot,double等)的属性必须声明成包装类型Integer,Float,Double
- 对于List这种非基本类型对象的判断,如果使用继续类声明属性,则代码不生产
解决方案:
先直接获取属性值后,再使用instanceof判断属性类型,这样不仅规避以上问题,而且性能更好
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
TestClazz object = new TestClazz(2);
Field field = ClassUtil.getDeclaredField(TestClazz.class, "prop");
field.setAccessible(true);
long times = 1000000;
long last = System.currentTimeMillis();
long aa = 0;
for (long i = 0; i < times; i++) {
String type = field.getGenericType().toString();
if ("class java.lang.Integer".equals(type)) {
Object o = field.get(object);
aa++;
}
}
System.out.println("getGenericType:" + (System.currentTimeMillis() - last));
System.out.println("times:" + aa);
last = System.currentTimeMillis();
aa = 0;
for (long i = 0; i < times; i++) {
Object o = field.get(object);
if (o instanceof Integer) {
aa++;
}
}
System.out.println("instance:" + (System.currentTimeMillis() - last));
System.out.println("times:" + aa);
}
static class TestClazz {
private Integer prop;
TestClazz(Integer prop) {
this.prop = prop;
}
public Integer getProp() {
return prop;
}
}
经测试性能相差10倍,结果如下
getGenericType:73
times:1000000
instanceof:6
times:1000000
Process finished with exit code 0
版权声明:本文为ceyowa原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。