【轉】FINDBUGS錯誤分析日誌

【轉】FINDBUGS錯誤分析日誌

     終於 我們又開始使用FINDBUGS來檢測代碼的問題了 但因沒又中文版和網上錯誤分析實際很少 所以自己邊處理BUG邊寫文檔

   首先在裝好FINDBUGS後 在 project-->properteis-->findbugs裏的2個框的勾點上可以讓改正BUG後自動判斷是否改正了 改正了就自動去掉BUG點

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()方法沒檢查空參數
      2B錯誤完全不解釋

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
     在可序列化的類中存在不能序列化或者不能暫存的數據


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章