1. 程式人生 > >FindBugs 錯誤資訊彙總

FindBugs 錯誤資訊彙總

1.Call to equals() comparing different type
   
    大部分都是型別永遠不會有這種情況 比如a為DOUBLE型別所以EQUALS只匹配字串 if(a.equals())或if(a.quals())這類判斷是根本不會有用的的

2.Class doesn't override equals in superclass

    super.equals(obj) 呼叫父類equals方法 一般都是Object的方法,所以這個super可寫可不寫,一般都是 為了程式碼的可讀性才加上去的

    一般就是重寫equals(obj)即可 即public boolean equals(Object obj){ return super.equals(obj);}
    但是如果覆蓋了equals()方法的話,則必須要覆蓋hashCode()方法。否則FINDBUGS會出現下面的7號BUG:覆蓋了equals()方法的話,則必須要覆蓋hashCode()方法
    所以 public boolean equals(Object obj){ return super.equals(obj);} 
         public int hashCode(){
   return super.hashCode();
}


3.Class is Serializable, but doesn't define serialVersionUID

    serialVersionUID 用來表明類的不同版本間的相容性

    簡單來說,Java的序列化機制是通過在執行時判斷類的serialVersionUID來驗證版本一致性的。在進行反序列化時,JVM會把傳來的位元組流中的serialVersionUID與本地      相應實體(類)的serialVersionUID進行比較,如果相同就認為是一致的,可以進行反序列化,否則就會出現序列化版本不一致的異常。

    當實現java.io.Serializable介面的實體(類)沒有顯式地定義一個名為serialVersionUID,型別為long的變數時,Java序列化機制會根據編譯的class自動生成一個       serialVersionUID作序列化版本比較用,這種情況下,只有同一次編譯生成的class才會生成相同的serialVersionUID 。

    如果我們不希望通過編譯來強制劃分軟體版本,即實現序列化介面的實體能夠相容先前版本,未作更改的類,就需要顯式地定義一個名為serialVersionUID,型別為long     的變數,不修改這個變數值的序列化實體都可以相互進行序列化和反序列化。

    也就是這個錯誤 你要定義一個名為 serialVersionUID,型別為long的變數 按照新版Eclipse自動填寫規則 就是:
     private static final long serialVersionUID = 1L;

4.Class names shouldn't shadow simple name of superclass


   嘛 基本就是這個類的名字跟超類的名字一樣但不在一個包裡 所以就改下類名啦

5.Comparison of String parameter using == or !=

   原因:當比較兩個字串內容是否相同時,僅當兩個字串在原始檔中都是常量時或者是使用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()方法在效率和實現方式上不統一)

6.Call to equals() comparing different types
    equals比較了不同的物件型別 說的是equals要比較相同的物件型別

7.Equals checks for noncompatible operand
    equals()方法比較的是值是否相同,而不是記憶體指向地址
   就實際情況來看 是因為
   public boolean equals(Object object) {
   if (!(object instanceof DmZzmm)) {
    return false;
   }
         Dxinfo rhs = (Dxinfo) object;
    return new EqualsBuilder().append(this.dxcount, rhs.dxcount).append(this.lxrsjh, rhs.lxrsjh)
      .append(this.dxnr, rhs.dxnr).append(this.fssj, rhs.fssj).append(this.fssl, rhs.fssl)
      .append(this.id,rhs.id).isEquals();
            。。。。
      } 
      問題在那裡?很簡單 這個白痴是拷貝的程式碼 既然object 不為DmZzmm就為false 而你要執行的是 Dxinfo rhs = (Dxinfo) object; 所以 如果為DMZzmm進入程式碼 會因      為不是 Dxinfo 型別而不執行下面的程式碼 如果為Dxinfo 型別 它就直接執行為FALSE!!所以程式碼毫無意義 只會執行false!!
      所以只需要把
      public boolean equals(Object object) {
   if (object instanceof Dxinfo) {
    Dxinfo rhs = (Dxinfo) object;
    。。。。。。。
   }else{
    return false;
   }
        就可以了 說穿了 就是你準備用instanceof 匹配的類要跟你下面執行的類要一致。。。。

8.equals method always returns false
   equals始終返回false
      嘛。。。就是沒繼承超類的話要自己寫個EQUALS。。。。別寫的沒意義只有false就是了。。
      public boolean equals(Object o) {
   return (this==o);
}

9.equals() method does not check for null argument
   equals()方法沒檢查空引數
10.Exception is caught when Exception is not thrown
    異常被捕獲但沒丟擲。。。。

     一般人都會這樣寫程式碼:


  try{
    //
  }
  catch(Exception ex){
    //
  }
    這樣很省事,但是JAVA規範中並不推薦這樣做,這樣是屬於“過泛地捕獲異常”,因為try{}中可能出現的異常種類有很多,上面的做法不利於分別處理各種異常,建議根     據業務需求,分別捕獲需要特別處理的異常,例子如下:


  try{
    //
  }
  catch(SQLException ex){
    //
  }
  catch(IOException ex){
    //
  }
  catch(Exception ex){
    //
  }
    另外一個是,捕獲到的Exception應儘量記錄到LOG檔案裡。


11.Field names should start with a lower case letter
    欄位名應該用小寫

12.Can't close pw since it is always null
    無法關閉【PW】因為總是為NULL

13.Non-transient non-serializable instance field in serializable class
     在可序列化的類中存在不能序列化或者不能暫存的資料

14.May expose internal representation by incorporating reference to mutable object

JAVA裡,物件是引用傳遞的,setObj的時候,物件不要直接賦值(this.regDate = regDate),可改為:this.regDate = (Date)regDate.clone();,

 15.Method names should start with a lower case letter
       函式的首字母應該小寫。

16.Uninitialized read of field in constructor
      建構函式沒有初始化;

 17.Method concatenates strings using + in a loop

The method seems to be building a String using concatenation in a loop. In each iteration, the String is converted to a StringBuffer/StringBuilder, appended to, and converted back to a String. This can lead to a cost quadratic in the number of iterations, as the growing string is recopied in each iteration.

Better performance can be obtained by using a StringBuffer (or StringBuilder in Java 1.5) explicitly.

For example:

// This is bad String s = ""; for (int i = 0; i < field.length; ++i) { s = s + field[i]; } // This is better StringBuffer buf = new StringBuffer(); for (int i = 0; i < field.length; ++i) { buf.append(field[i]); } String s = buf.toString();