`
scholers
  • 浏览: 614849 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

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

阅读更多
错误码:DM_FP_NUMBER_CTOR


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方法

类似的案例





类似的还有:
错误码: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)里面做了什么优化:
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。



错误码:DM_BOOLEAN_CTOR


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

int iTemp = sellerId.hashCode();
       if(iTemp != Integer.MIN_VALUE) {
         number = Math.abs(iTemp) % 12;
} else {
       number = Integer.MIN_VALUE % 12;
}


  • 大小: 35.2 KB
  • 大小: 7.9 KB
  • 大小: 5.1 KB
1
1
分享到:
评论

相关推荐

    fingbugs Java Bug检查工具

    Findbugs工具使用方便,检查java代码bug能力极强,是Java程序员必备的工具之一。

    fingbugs使用

    fingbugsfingbugsfingbugs

    fingbugs.zip

    FindBugs 是一个静态分析工具,它检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比以发现可能...不是通过分析类文件的形式或结构来确定程序的意图,而是通常使用 Visitor 模式来鉴别代码是否符合一些固定的规范。

    findbugs应用eclipse的插件

    findbugs 代码检查 eclipse插件 3.0.0版本

    findbugs eclipse插件

    最新版的fingbugs eclipse plugin,08年5月份更新的,超好用的静态分析工具。

    findbugs的架包

    findbugs的架包。直接放入eclipse中的plugin包中,然后重启eclipse就可以看到。

Global site tag (gtag.js) - Google Analytics