从 FingBugs的错误来看JAVA代码质量(二)

错误码:DM_FP_NUMBER_CTOR 
从 FingBugs的错误来看JAVA代码质量(二) - 火木棉 - 淡泊明智
 
Bug: Method OnlineLicenseDAOTest.testUpdateOnlineLicenseByOnlineMerchantId() invokes inefficient Double.valueOf(double) constructor; use OnlineLicenseDAOTest.java:[line 81] instead
Pattern id: DM_FP_NUMBER_CTOR, type: Bx, category: PERFORMANCE
Using new Double(double) is guaranteed to always result in a new object whereas Double.valueOf(double) 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.
Unless the class must be compatible with JVMs predating Java 1.5, use either autoboxing or the valueOf() method when creating instances of Double and Float.
解释:
采用new Ddouble(double)会产生一个新的对象,采用 Ddouble.valueOf(double)在编译的时候可能通过缓存经常请求的值来显著提高空间和时间性能。
解决方法:
采用Ddouble.valueOf方法
类似的案例 
从 FingBugs的错误来看JAVA代码质量(二) - 火木棉 - 淡泊明智
 
类似的还有:
错误码:DM_NUMBER_CTOR
new Integer(int) 和 Integer.valueOf(int) 
bug描述:
[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.
说明:
[参考]http://www.cnblogs.com/hyddd/articles/1391318.html
FindBugs推荐使用Integer.ValueOf(int)代替new Integer(int),因为这样 可以提高性能。如果当你的int值介于-128~127时,Integer.ValueOf(int)的效率比Integer(int)快大约3.5倍。
下面看看JDK的源码,看看到Integer.ValueOf(int)里面做了什么优化:
Java代码 复制代码  收藏代码 从 FingBugs的错误来看JAVA代码质量(二) - 火木棉 - 淡泊明智
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的缓存给你。
所以你会看到这样的一个现象:
Java代码 复制代码 收藏代码从 FingBugs的错误来看JAVA代码质量(二) - 火木棉 - 淡泊明智
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
再看看这段代码:
Java代码 复制代码 收藏代码从 FingBugs的错误来看JAVA代码质量(二) - 火木棉 - 淡泊明智
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。
错误码:DM_BOOLEAN_CTOR 

从 FingBugs的错误来看JAVA代码质量(二) - 火木棉 - 淡泊明智

 
Bug: Bad attempt to compute absolute value of signed 32-bit hashcode
Pattern id: RV_ABSOLUTE_VALUE_OF_HASHCODE, type: RV, category: CORRECTNESS
This code generates a hashcode and then computes the absolute value of that hashcode. If the hashcode is Integer.MIN_VALUE, then the result will be negative as well (since Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE).
One out of 2^32 strings have a hashCode of Integer.MIN_VALUE, including "polygenelubricants" "GydZG_" and ""DESIGNING WORKHOUSES".
解释:
此代码产生的哈希码,然后计算该哈希码的绝对值。如果哈希码是Integer.MIN_VALUE的,那么结果将是负面的,以及(因为Math.abs(Integer.MIN_VALUE的)==Integer.MIN_VALUE的)。
解决方法:
在使用之前判断一下是否是为Integer.MIN_VALUE
Java代码 复制代码 收藏代码从 FingBugs的错误来看JAVA代码质量(二) - 火木棉 - 淡泊明智
int iTemp = sellerId.hashCode();   
       if(iTemp != Integer.MIN_VALUE) {   
         number = Math.abs(iTemp) % 12;   
} else {   
       number = Integer.MIN_VALUE % 12;   
}  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值