FindBugs工具常見問題

1,AM: Creates an empty jar file entry (AM_CREATES_EMPTY_JAR_FILE_ENTRY)/AM: Creates an empty zip file entry (AM_CREATES_EMPTY_ZIP_FILE_ENTRY)java

示例代碼:dom

ZipEntry entry = new ZipEntry(PATH);函數

zos.putNextEntry(entry);字體

zos.closeEntry();code

緣由:對象

代碼中在調用putNextEntry()以後緊接着調用了closeEntry()函數,導致該jar文件內容爲空,由於打jar包的寫內容是在putNextEntry()和closeEntry()兩個函數調用之間來進行的。(有時候也許會有意的構建一個空目錄,所以不必定就是bug)blog

 

2,BC: Equals method should not assume anything about the type of its argument (BC_EQUALS_METHOD_SHOULD_WORK_FOR_ALL_OBJECTS)繼承

 

示例代碼:接口

public class Foo {ip

   // some code

   public void equals(Object o) {

     Foo other = (Foo) o;

    // the real equals code

  }

}

緣由:

當你在實現類的equals方法時,不該該對參數有任何的預先設定。如上代碼所寫,則設定了參數o確定是Foo類的一個對象.可是若是在函數調用時,參數o不是一個Foo類或其子類,就會致使代碼會拋出一個ClassCastException。所以在實現equals方法,應該加一個判斷,若是參數o不是一個Foo類對象,則返回false。

 

3,BC: Random object created and used only once (DMI_RANDOM_USED_ONLY_ONCE)

示例代碼:

public int getRandom(int seed) {

    return new Random(seed).nextInt();

}

緣由:

因爲java.util.Random是一個僞隨機函數,若是傳入的seed值相同的話,返回的隨機數者是相同的 。所以不必每次都new一個新的random出來計算隨機數。若是你想真正地得到一個不可預知的隨機數,建議使用java.security.SecureRandom,該類繼承自Random,是一個強隨機數生成器 。所以上述代碼能夠修改成:

public class Test  extends Thread{

    private SecureRandom ran;

 

    Test(int seed){

        ran = new SecureRandom();

    }

    

    public int getRandom(int seed) {

        return ran.nextInt();

    }

}

 

4,CN: Class implements Cloneable but does not define or use clone method (CN_IDIOM)

示例代碼:

public class Foo implements Cloneable {

         public Object clone() throws CloneNotSupportedException {

                   return super.clone();

         }

}

緣由:

類定義要實現了 Cloneable接口,卻沒有定義或使用 clone方法,即缺乏紅色字體部分。

 

5,CN: clone method does not call super.clone() (CN_IDIOM_NO_SUPER_CALL)

示例代碼:

public class Foo implements Cloneable {

         public Object clone() throws CloneNotSupportedException {

                   return super.clone();

         }

}

緣由:

clone方法沒有調用super.clone()方法,若是沒有調用,則會致使對象父子層級關係不能正確創建,最終致使沒法正確組裝對象。

 

6,CN: Class defines clone() but doesn't implement Cloneable (CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE)

示例代碼:

public class Foo{

         public Object clone() throws CloneNotSupportedException {

                   return super.clone();

         }

}

緣由:

這個用法的意義在於你能夠規範該類的子類的clone的實現,若是你的確想這樣作的話,這不是一個bug,不然的話是一個bug

 

7,DE: Method might drop exception (DE_MIGHT_DROP)/DE: Method might ignore exception (DE_MIGHT_IGNORE)

 

示例代碼:

try{}catch(Exception ex){}

緣由:

方法有可能拋異常或者忽略異常,須要對異常進行處理,即須要在catch體中對異常進行處理。

 

8,DMI: Don't use removeAll to clear a collection (DMI_USING_REMOVEALL_TO_CLEAR_COLLECTION)

緣由:

建議不要使用 collection.removeAll(collection)方法來刪除 collection中的全部元素,而使用collection.clear()。比較兩者的代碼實現就能夠看出:

removeAll()源碼:

    public boolean removeAll(Collection<?> c) {

              boolean modified = false;

              Iterator<?> e = iterator();

              while (e.hasNext()) {

                    if (c.contains(e.next())) {

                                 e.remove();

                                 modified = true;

                  }

              }

              return modified;

    }

clear()源碼:

    public void clear() {

              Iterator<E> e = iterator();

              while (e.hasNext()) {

                  e.next();

                  e.remove();

              }

    }

前者是比較參數中的collection和要移除元素的collection中是否有交集,而後將交集元素刪除;後者是直接將collenction中的元素刪除。顯而後者要比前者高效,並且對於某些特殊的collenction還容易拋出一些異常,如ConcurrentModificationException

9,ES: Comparison of String parameter using == or != (ES_COMPARING_PARAMETER_STRING_WITH_EQ)

緣由:當比較兩個字符串內容是否相同時,僅當兩個字符串在源文件中都是常量時或者是使用intern()來比較才能夠用==來比較,不然最好使用對象比較方法equal。附string比較:

String str1 = "java";

String str2 = "java";

System.out.print(str1==str2);

結果:true(兩者都爲常量)

String str1 = new String("java");

String str2 = new String("java");

System.out.print(str1==str2);

結果:false(兩者爲對象)

String str1 = "java";

String str2 = "blog";

String s = str1+str2;

System.out.print(s=="javablog");

結果:false(s不爲常量,爲對象)

String s1 = "java";

String s2 = new String("java");

System.out.print(s1.intern()==s2.intern());

結果:true(可是intern()方法在效率和實現方式上不統一)

相關文章
相關標籤/搜索