`
ihyperwin
  • 浏览: 432697 次
  • 性别: 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错误码对照表

    以下是对FindBugs错误码及其含义的详细解释: 1. Dm: Hardcoded constant database password (DMI_CONSTANT_DB_PASSWORD) 这个错误表示在代码中直接使用了硬编码的数据库密码。这样做不仅不安全,还可能导致密码...

    findbugs-3.0.1.zip

    《FindBugs 3.0.1:Java代码静态分析工具深度解析》 FindBugs是一款广受欢迎的开源工具,用于检测Java代码中的潜在错误和不良编程习惯。在"findbugs-3.0.1.zip"这个压缩包中,包含了FindBugs 3.0.1版本的详细资料和...

    findbugs-1.3.9.tar.zip

    FindBugs是一款强大的开源代码静态分析工具,其1.3.9版本的发布为开发者提供了一种高效、全面的方式来检测Java程序中的潜在错误和不良编程习惯。它通过扫描字节码而非源代码,能够在不运行程序的情况下找出可能的...

    FindBugs插件的安装及使用方法.docx

    FindBugs是一款用于静态分析Java代码的工具,它可以帮助开发者在早期阶段发现潜在的错误和漏洞,从而提高软件的质量和可靠性。FindBags通过扫描类文件或JAR文件来查找可能存在的问题,这些问题包括但不限于空指针...

    Gradle平台集成静态代码检查(findbugs,pmd,checkstyle)

    - **Findbugs**:这是一个分析Java字节码,查找可能导致错误的bug模式的工具。Findbugs可以检测出Java源代码中隐藏的bug,例如空指针异常、并发问题、错误的API使用等。 - **Checkstyle**:此工具主要用于检查Java...

    Log4j_CheckStyle_FindBugs

    综上所述,"Log4j_CheckStyle_FindBugs" 是一种最佳实践,它利用了Log4j的日志功能、Checkstyle的编码规范检查和FindBugs的静态分析,共同提升了Java开发的质量和可靠性。通过掌握这三个工具的使用,开发者不仅可以...

    findbugs-1.3.9.tar.gz + protobuf-2.5.0.tar.gz +snappy-1.1.1.tar.

    - FindBugs是一款静态代码分析工具,主要用于Java程序的错误检测。1.3.9是其版本号。 - 它能够通过分析字节码来寻找潜在的错误和不良编程实践,如空指针异常、资源泄漏、并发问题等。 - 使用FindBugs可以帮助...

    FindBugs规则整理_中文版.pdf

    它通过对代码进行分析而无需实际执行,找出可能存在的缺陷、错误或者不良编程习惯。FindBugs将这些问题分为不同的类别,包括安全性(Security)、实验性(Experimental)等,帮助开发者提高代码质量和安全性。 1. *...

    hudson插件加载失败解决方案.pdf

    本文档将讨论hudson插件加载失败的解决方案,涵盖hudson版本、环境信息、插件安装、Tomcat日志分析、问题排查等方面的知识点。 一、hudson版本信息 hudson版本:hudson-2.2.1.war hudson是一个基于Java的开源持续...

    java java查bug 查bug bug 查错 源码

    总之,Java查bug和查错是一项系统性工作,需要结合多种方法和技术,包括使用调试工具、分析日志、编写测试、代码审查以及理解和阅读源码。而像FindBugs这样的静态分析工具,更是能提升代码质量,减少bug的发生。对于...

    Lab-4 1160300314 朱明彦 report 1

    - **日志查询** 涉及到检索和分析日志信息,以找出可能导致问题的模式或趋势。 **测试和调试** 3.4部分介绍了测试的策略和设计,以及如何利用工具进行调试。 - **测试策略** 包括针对不同组件(如Graph、Vertex和...

    Java语言的程序漏洞检测与诊断技术应用研究.zip

    日志分析是常见的一种,通过收集和分析程序运行时的日志信息,可以帮助定位错误发生的位置。调试器如JDB或Eclipse的内置调试器,能帮助开发者逐行执行代码,观察变量状态,查找问题根源。此外,代码审查也是重要的...

    Java语言的程序漏洞分析技术研究.zip

    6. 配置错误:不正确的系统或应用配置可能导致安全漏洞,例如公开敏感的日志文件或过度的权限分配。 Java程序漏洞分析技术主要包括静态分析和动态分析两种方法: 1. 静态分析:这种方法在不执行代码的情况下分析...

    Java问题定位技术.rar

    使用如Log4j、SLF4J等日志框架能帮助开发者更好地管理和分析日志。 2. **异常堆栈跟踪**:当程序抛出异常时,会伴随着堆栈跟踪信息,它列出了异常发生时执行的代码路径。通过对堆栈跟踪的分析,可以追踪到问题的...

    Lab-5-1160300314-朱明彦-Report1

    - **-verbose:gc参数**:开启JVM的垃圾收集日志,帮助分析垃圾回收过程。 - **jstat命令**:用于监控Java虚拟机的各种统计信息,包括垃圾收集状态。 - **jmap命令**:用于获取堆内存详细信息,例如`-heap`选项...

    sonar代码管理工具6.7.5

    PMD专注于代码风格和潜在错误,而FindBugs则擅长发现可能的运行时错误,两者结合,可以全面提高代码质量。 其次,SonarQube提供了一种集中的平台,可以在上面查看所有项目的代码质量报告。它具有丰富的可视化界面,...

    运行期代码问题检查技术的研究

    还有像PMD、FindBugs(现在称为ErrorProne)这样的静态分析工具,可以在代码编译阶段发现潜在问题。 BugDetector可能是一个专有的工具或者文章中提到的特定工具,用于检测运行时错误,如空指针异常、数组越界等。...

    java静态代码分析插件checkstyle的应用

    此外,Checkstyle还可以与其他静态代码分析工具(如PMD、FindBugs)结合使用,提供更全面的代码质量保证。 在大型项目中,Checkstyle的应用可以显著提高代码质量和团队协作效率。它不仅减少了代码审查的工作量,...

Global site tag (gtag.js) - Google Analytics