代码改变世界

[hyddd的FindBugs分析记录][M P Bx] Method invokes inefficient Number constructor; use static valueOf instead

2009-02-16 11:01  hyddd  阅读(3126)  评论(0编辑  收藏  举报

[M P Bx] Method invokes inefficient Number constructor; use static valueOf instead [DM_NUMBER_CTOR]

Using new Integer(int) is guaranteed to always result in a new object whereas Integer.valueOf(int) allows caching of values to be done by the compiler, class library, or JVM. Using of cached values avoids object allocation and the code will be faster.

Values between -128 and 127 are guaranteed to have corresponding cached instances and using valueOf is approximately 3.5 times faster than using constructor. For values outside the constant range the performance of both styles is the same.

Unless the class must be compatible with JVMs predating Java 1.5, use either autoboxing or the valueOf() method when creating instances of Long, Integer, Short, Character, and Byte.

 

这里,FindBugs推荐使用Integer.ValueOf(int)代替new Integer(int),因为这样可以提高性能。如果当你的int值介于-128~127时,Integer.ValueOf(int)的效率比Integer(int)快大约3.5倍。

下面看看JDK的源码,看看到Integer.ValueOf(int)里面做了什么优化:

public static Integer valueOf(int i) {
  
final int offset = 128;
  
if (i >= -128 && i <= 127) { // must cache
    return IntegerCache.cache[i + offset];
  }
  
return new Integer(i);




private static class IntegerCache {
  
private IntegerCache(){}
    
  
static final Integer cache[] = new Integer[-(-128+ 127 + 1];
  
static {
  
for(int i = 0; i < cache.length; i++)
     cache 
= new Integer(i - 128);
  }
}

从源代码可以知道,ValueOf对-128~127这256个值做了缓存(IntegerCache),如果int值的范围是:-128~127,在ValueOf(int)时,他会直接返回IntegerCache的缓存给你。

 

所以你会看到这样的一个现象:

public static void main(String []args) {
     Integer a 
= 100;
     Integer b 
= 100;
     System.out.println(a
==b);

     Integer c 
= new Integer(100);
     Integer d 
= new Integer(100);
     System.out.println(c
==d);
}

结果是:

true
false

因为:java在编译的时候 Integer a = 100; 被翻译成-> Integer a = Integer.valueOf(100);,所以a和b得到都是一个Cache对象,并且是同一个!而c和d是新创建的两个不同的对象,所以c自然不等于d。

 

再看看这段代码:

public static void main(String args[]) throws Exception{
        Integer a 
= 100;
        Integer b 
= a;
        a 
= a + 1;  //或者a++;
        System.out.println(a
==b);
}
结果是:false

因为在对a操作时(a=a+1或者a++),a重新创建了一个对象,而b对应的还是缓存里的100,所以输出的结果为false。

 

参考资料:

1.http://hi.baidu.com/zhaochengming/blog/item/37495c3b20994ae814cecb65.html