從 FingBugs的錯誤來看JAVA代碼質量(二)

[b]錯誤碼:DM_FP_NUMBER_CTOR[/b]
[img]http://dl.iteye.com/upload/attachment/506031/5e977a03-02fd-34d8-ba0f-6d157b507371.jpg[/img]

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.
[b]解釋:[/b]
採用new Ddouble(double)會產生一個新的對象,採用Ddouble.valueOf(double)在編譯的時候可能通過緩存經常請求的值來顯著提高空間和時間性能。

[b]解決方法:[/b]
採用Ddouble.valueOf方法

類似的案例



[img]http://dl.iteye.com/upload/attachment/506033/37e7b373-56db-3176-8a46-e2137eb82cd4.jpg[/img]

類似的還有:
錯誤碼: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
[img]http://dl.iteye.com/upload/attachment/506042/def3566f-e95a-319a-926a-c5c6811d1728.jpg[/img]

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".
[b]解釋:[/b]
此代碼產生的哈希碼,然後計算該哈希碼的絕對值。如果哈希碼是Integer.MIN_VALUE的,那麼結果將是負面的,以及(因爲Math.abs(Integer.MIN_VALUE的)==Integer.MIN_VALUE的)。

[b]解決方法:[/b]
在使用之前判斷一下是否是爲Integer.MIN_VALUE

int iTemp = sellerId.hashCode();
if(iTemp != Integer.MIN_VALUE) {
number = Math.abs(iTemp) % 12;
} else {
number = Integer.MIN_VALUE % 12;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章