`
ihyperwin
  • 浏览: 426774 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

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();
     }

此处,借鉴国外的资料:

findbugs: Class doesn't override equals in superclass
This class extends a class that defines an equals method and adds fields, but doesn't define an equals method itself. Thus, equality on instances of this class will ignore the identity of the subclass and the added fields. Be sure this is what is intended, and that you don't need to override the equals method. Even if you don't need to override the equals method, consider overriding it anyway to document the fact that the equals method for the subclass just return the result of invoking super.equals(o).

大概翻译下:
这个类继承了一个定义了(重写了)equals方法并且又增加了字段,但是自己没有定义(重写 override)一个equals方法。
因此,这个类判断实例相等时会忽视掉子类的相等和字类的成员变量值。
你如果确定这就是你想要的,你可以不必重写这个equals方法。尽管你不需要重写equals方法,也要考虑一下重写equals方法,可以这样:子类的equals方法只return 调用
super.equals(0)的结果就行了。


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
     在可序列化的类中存在不能序列化或者不能暂存的数据


百度文库链接地址   http://wenku.baidu.com/view/fd012b6d58fafab069dc0227.html


-----------------------------------------------------------------------------------------------------


1  Comparison of String objects using == or !=
    例,override equals方法时容易犯错
if(this.topic != key.getTopic())
    return false;
2 Dead store to newStatusRecord
    定义局部变量后没有引用

3 Invocation of toString on values
   直接调用数组的toString方法
public  Query createQuery(String hql, Object values[],Session session){
  logger.debug(values);
  logger.debug((new StringBuilder()).append("hql=[").append(hql).append("] ").append(((Object)
}

正确的例子,调用Arrays.toString()和Arrays.deepToString()方法。
import java.util.Arrays;
class A{

}
class B{
@Override
public String toString() {
  return "BBBBB";
}
}
public class Test {
public static void main(String[] args) {
 
  Object [] a = {new Integer(0),new Boolean(true),true,new A(),new B()};
 
  Object[][]b ={{new A(),new B()},{new A(),new B()},{new A(),new B()}};
  System.out.println(Arrays.deepToString(b));
 
}
}

4 ignores exceptional return value of java.io.File.mkdirs()
忽略了返回值,应当含有返回值
  public void initFolder() {
if (!exitDir.isDirectory())  {
   exitDir.mkdirs();
   logger.info("===Finishing create exit trade image folder!====");
  }
}
This method returns a value that is not checked. The return value should be checked since it can indicate an unusual or unexpected function execution. For example, the File.delete() method returns false if the file could not be successfully deleted (rather than throwing an Exception). If you don't check the result, you won't notice if the method invocation signals unexpected behavior by returning an atypical return value.
5 不使用new String()定义空的字符串
String alarmCodeCond = new String();
应当
String alarmCodeCond = "";
6 invokes inefficient new Short(short) constructor; use Short.valueOf(short) instead
    JVM缓存数字常量
Short aShort = new Short(12);
应当
Short aShort = Short.valueOf(12);
7 方法命名习惯,首字母小写
     The method name LaneHandShakeService(Short) doesn't start with a lower case letter
     Methods should be verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized.

8  一个primtive的类型的值经过box后马上unbox
Primitive value is boxed then unboxed to perform primitive coercion

exitRecord.setEnOperatorId(new Long(transactRecord.getEnoperatorID()).intValue());
应当直接强制类型转换
exitRecord.setEnOperatorId((int)transactRecord.getEnoperatorID());
9 Call to equals() comparing different types
使用equals()方法比较不同的类,
反例
  StringBuilder builder = new StringBuilder("nihao");
  String string = "nihao";
  builder.equals(string);
10  Check for oddness that won't work for negative numbers
检查奇数的方法:
反例
   if (i % 2 == 1) {
    //...
   }
The code uses x % 2 == 1 to check to see if a value is odd, but this won't work for negative numbers (e.g., (-5) % 2 == -1). If this code is intending to check for oddness, consider using x & 1 == 1, or x % 2 != 0.

11 Load of known null value,null值的不当使用
反例:
if (devIds == null && devIds.size() == 0) {  //...  }

if (null != tempList || tempList.size() != 0) {
            //...
}
if (batchNo == null) {
   throw new Exception("the No. " + batchNo
     + " is not exists!");
  }
12  Method call passes null for nonnull parameter
    对参数为null的情况没做处理
    例

public void method1() {
   String ip = null;
  try {
   ip = InetAddress.getLocalHost().getHostAddress();
  } catch (UnknownHostException e) {
   e.printStackTrace();
  }
  long ipCount = countIpAddress(ip); // 可能会传入空引用
                               //...
}
long countIpAddress(String ip) {
  long ipNum = 0;
  String[] ipArray = ip.split("\\.");
}

修改后:
public void method1() {
   String ip = null;
  try {
   ip = InetAddress.getLocalHost().getHostAddress();
  } catch (UnknownHostException e) {
   e.printStackTrace();
  }
  long ipCount = countIpAddress(ip); // 可能会传入空引用
                               //...
}
long countIpAddress(String ip) {
  long ipNum = 0;
  if (ip == null) {
   return 0;          //或者抛出异常
  }
  String[] ipArray = ip.split("\\.");
                               //...
}

注意:函数入口需要交验入参的合法性。

13 Method concatenates strings using + in a loop
在循环里使用字符串连接,效率低,应该使用StringBuilder/StringBuffer
例:

    String writeData = "";
    for (int i = 0; i < 10; i++) {
     writeData = writeData + "a";
    }
14 Method may fail to close database resource
   没有释放数据库资源
public ResultSet callProcedure(String procedure) {
  Session ses = getSessionForUpdate();
  ResultSet rs = null;
  try {
   Connection conn = ses.connection();
   conn.setAutoCommit(false);
   CallableStatement statement = conn.prepareCall(procedure); //may fail to close CallableStatement
   rs = statement.executeQuery();
   conn.commit();
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   try {
    ses.close();
   } catch (SQLException e) {
    throw e;
   }
  }
  return rs;
}
应当修改为:
public ResultSet callProcedure(String procedure) {
  Session ses = getSessionForUpdate();
  ResultSet rs = null;
  CallableStatement statement = null;
  try {
   Connection conn = ses.connection();
   conn.setAutoCommit(false);
   statement = conn.prepareCall(procedure);
   rs = statement.executeQuery();
   conn.commit();
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   try {
    statement.close();
    ses.close();
   } catch (SQLException e) {
    e.printStackTrace();
   }
  }
  return rs;
}
15 Method may fail to close stream
    没有关闭流,可能会导致文件描述符泄露,应该在finally中关闭
   例:
  try {
   FileInputStream in = new FileInputStream(file);
   InputStreamReader inputStreamReader = new InputStreamReader(in);
   BufferedReader reader = new BufferedReader(inputStreamReader);
   //...
   in.close();
   inputStreamReader.close();
   reader.close();
  } catch (IOException e) {
  }
  修改为:
  FileInputStream in = null;
  InputStreamReader inputStreamReader = null;
  BufferedReader reader = null;
  try {
   in = new FileInputStream(file);
   inputStreamReader = new InputStreamReader(in);
   reader = new BufferedReader(inputStreamReader);
   // ...
  } catch (IOException e) {
  } finally {
   try {
    in.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
   try {
    inputStreamReader.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
   try {
    reader.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
16 Method might ignore exception
  
This method might ignore an exception.  In general, exceptions should be handled or reported in some way, or they should be thrown out of the method.
应该将异常 处理、打印或者抛出
反例:
try {
     //...
     } catch (Exception e) {

     }
17 Class defines non-transient non-serializable instance field readerTypeInfo
一个实现了Serializable接口的类,含有非transient 和非serializable 的实例对象域。

This Serializable class defines a non-primitive instance field which is neither transient, Serializable, or java.lang.Object, and does not appear to implement the Externalizable interface or the readObject() and writeObject() methods.  Objects of this class will not be deserialized correctly if a non-Serializable object is stored in this field.

18 Nullcheck of value previously dereferenced
前面获取的对象,现在引用的时候没有交验是否为null
反例:
  Reader reader = null;
  try {
   reader = this.getReaderByName(readerBasicInfo.getByName());
  }  catch (Exception e1) {
   e1.printStackTrace();
   return ReaderStateConst.FAIL;
  }
  DependenceRelation dependenceRelation = new DependenceRelation();
  dependenceRelation.setDescription(reader.getIpAddress());  // 使用前没有做null校验
19  Possible null pointer dereference
   可能存在的空引用
  capInfo = wrapper.wrapperToClient((ReaderCapabilities) object);
  try {
   if (capInfo != null) {
    transactionDs
      .saveReaderCapabilityCom((ReaderCapabilities) object);
   }
  } catch (RuntimeException e) {
   capInfo.setDetailMsg(ReaderStateConst.DB_OPT_FAIL);
   return capInfo;
  }
  capInfo.setDetailMsg(ReaderStateConst.SUCCESSFUL);   //capInfo可能为null
20 引用前需要做空校验
public synchronized void remove(String batNo, int count) {
  List<Task> taskList = commandMap.get(batNo);
  synchronized (taskList) { //使用前需要作null check
   //...
  }
}

21 Possible null pointer dereference in method on exception path

  List<District> districts = null;
  try {
   districts = this.getDistricts(ReaderConst.DESC);
  } catch (Exception e) {
   e.printStackTrace();
  }
  if (start >= districts.size()) { //districts 可能是null
   tableData.setTotalCount(0);
   return tableData;
  }
22 内部类没有引用外部类的属性/方法的时候,应该作为静态内部类。
This class is an inner class, but does not use its embedded reference to the object which created it.  This reference makes the instances of the class larger, and may keep the reference to the creator object alive longer than necessary.  If possible, the class should be made static.

23 包装类的比较应该使用 eueqls,要比较值类型,需要强制类型转换后再使用。
This method compares two reference values using the == or != operator, where the correct way to compare instances of this type is generally with the equals() method. It is possible to create distinct instances that are equal but do not compare as == since they are different objects. Examples of classes which should generally not be compared by reference are java.lang.Integer, java.lang.Float, etc.
例 getTypeCodeID() 和getSpecCodeID() 方法均返回Integer

  if (configReaderInfo.getTypeCodeID() == realReaderInfo.getTypeCodeID()
    && configReaderInfo.getSpecCodeID() == realReaderInfo
      .getSpecCodeID()) {
   return true;
  }
public class NumberTest {
public static void main(String[] args) {
  Integer a = new Integer(1);
  Integer b = new Integer(1);
  System.out.println(a == b);  //结果是false
}
}

24 Write to static field from instance method
  不要通过实例方法给静态变量赋值。
分享到:
评论

相关推荐

    FindBugs错误分析说明.pdf

    FindBugs错误分析说明包含了常见错误,有针对性的讲解,且有相应实例对照。对java编程者非常有帮助。

    eclipse插件FindBugs错误分析说明

    主要是eclipse插件FindBugs中错误的解释说明,帮助定位错误原因

    findbugs错误类型的中文解释

    findbugs错误类型的中文解释 findbugs 错误类型 中文解释 bug type

    findbugs的错误类型整理

    共整理了findbugs错误类型37个,有错误举例,同时附有正确写法。

    FindBugs错误修改指南

    FindBugs错误修改指南

    FindBugs错误码对照表

    findbugs对照表。错误表,eclipsebug表。这个用于在eclipse中使用findbugs插件,后显示的错误对照表。可以帮助快速查询原因

    findbugs 1.3.9 findbugs 1.3.9

    findbugs 1.3.9 findbugs 1.3.9 findbugs 1.3.9 findbugs 1.3.9 findbugs 1.3.9 findbugs 1.3.9

    FindBugs常见错误码

    FindBugs常见错误码,中文详细解说,对一千多钟错误做了详细的分析讲解。

    静态分析工具FindBugs

    java静态分析工具 FindBugs java静态分析工具 FindBugs

    findbugs3.0.2插件 myeclipse

    FindBugs 是由马里兰大学提供的一款开源 Java静态代码分析工具。FindBugs通过检查类文件或 JAR文件,将字节码与一组缺陷模式进行对比从而发现代码缺陷,完成静态代码分析。FindBugs既提供可视化 UI 界面,同时...

    FindBugs Java静态代码分析工具

    FindBugs是一款Java静态代码分析工具,与其他静态分析工具(如Checkstyle和PMD)不同,FindBugs 不注重样式或者格式,它专注于寻找真正的缺陷或者潜在的性能问题,它可以帮助java工程师提高代码质量以及排除隐含的...

    findbugs-maven-plugin, 为了生成基于FindBugs分析器的报告,Maven Mojo插件.zip

    findbugs-maven-plugin, 为了生成基于FindBugs分析器的报告,Maven Mojo插件 Maven 插件 最新快照请从这里下载最新的快照。构建findbugs-maven-plugin需求Java 7是必需的。这将允许分析字节码到 Java 8 findbugs-...

    findbugs-2.0.1

    在这个由两部分组成的系列文章的第一部分中,高级软件工程师 Chris Grindstaff 分析了 FindBugs 如何帮助提高代码质量以及排除隐含的缺陷。代码质量工具的一个问题是它们容易为开发人员提供大量但并非真正问题的问题...

    findbugs压缩包+findbugs.jar+findbugs-ant.jar

    用于findbugs安装配置,及findbugs结果导出分析文档

    findbugs1.3.8错误类型说明及中文对照

    findbugs1.3.8错误类型说明及中文对照

    java代码分析工具findbugs安装使用说明及常见错误

    findbugs是一款基于eclipse的java静态代码分析工具,其中包含findbugs安装包,安装使用说明及常见错误的分析和解释

    findbugs(3.01).zip

    FindBugs 是一个静态分析工具,它检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题。有了静态分析工具,就可以在不实际运行程序的情况对软件进行分析。不是通过分析类文件的形式或结构来确定...

    findbugs插件 myeclipse

    FindBugs通过检查类文件或 JAR文件,将字节码与一组缺陷模式进行对比从而发现代码缺陷,完成静态代码分析。FindBugs既提供可视化 UI 界面,同时也可以作为 Eclipse插件使用。文本将主要使用将 FindBugs作为 Eclipse...

    findbugs工具测试java实验报告

    利用findbugs工具测试java实验报告,里面有详细的测试内容和方案可以作为课程设计用 如果有帮助到了你 请给个好评谢谢

    findbugs-annotations-1.3.9-1-API文档-中文版.zip

    赠送jar包:findbugs-annotations-1.3.9-1.jar; 赠送原API文档:findbugs-annotations-1.3.9-1-javadoc.jar; 赠送源代码:findbugs-annotations-1.3.9-1-sources.jar; 赠送Maven依赖信息文件:findbugs-...

Global site tag (gtag.js) - Google Analytics