使用instanceof代替getGenericType()获得10倍性能优化

使用instanceof代替getGenericType优化对象判断

问题发现:

在走读业务代码过程中发现存在如下情况,大致可以推测,代码原本是希望通过判断属性声明类型来作不同的业务处理,但使用的是先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")){
	//业务代码;
}

这样做存在两个问题:

  1. 如果属性使用的int基本类型进行声明,则代码对基本类型的判断就是错误的,如int属性的getGenericType().toString()获得的就是‘int’
  2. 这样相当于隐式的要求基本类型(int,flot,double等)的属性必须声明成包装类型Integer,Float,Double
  3. 对于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版权协议,转载请附上原文出处链接和本声明。