findbugs规则整理及解决办法

  • Post author:
  • Post category:其他

  1. A boxed primitive is created from a String, just to extract the unboxed primitive value. It is more efficient to just call the static parseXXX method.
    修改建议:使用Long.ParseLong,避免自动装箱再拆箱
    问题原因:
    Long.ParseLong(String)方法,将 string 参数解析为有符号十进制 ,返回一个long的基本类型值
    Long.ValueOf(String) ,方法得到的值非常相似。只是最后被转换为一个Long的包装类
  2. 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.
    修改建议:若成员类中未访问外围类的非静态成员,为避免额外的空间和时间开销,建议改用静态成员类。
    问题原因:
    非静态成员类和静态成员类的区别在于,非静态成员类是对象的,静态成员类是类的。非静态成员类可以访问外围类的任何成员,但前提是必须存在外围类对象。JAVA需要额外维护非静态成员类和外围类对象的关系。
  3. This code generates a hashcode and then computes the absolute value of that hashcode. If the hashcode is Integer.MIN_VALUE, then the result will be negative as well (since Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE).
    One out of 2^32 strings have a hashCode of Integer.MIN_VALUE, including “polygenelubricants” “GydZG_” and “”DESIGNING WORKHOUSES”.
    修改建议:在使用之前判断一下是否是为Integer.MIN_VALUE
    问题原因:
    此代码产生哈希码,然后计算该哈希码的绝对值。如果哈希码是Integer.MIN_VALUE的,那么结果将是负的(因为Math.abs(Integer.MIN_VALUE)==Integer.MIN_VALUE)。
  4. A boxed value is unboxed and then immediately reboxed.
    修改建议:三元运算符两个分支的返回类型保持一致。
    问题原因:
    装箱的值被拆箱,然后立刻重新装箱
  5. This class defines a field with the same name as a visible instance field in a superclass. This is confusing, and may indicate an error if methods update or access one of the fields when they wanted the other.
    修改建议:要么去掉其中一个字段,要么重新命名。
    问题原因:
    变量与超类中的可访问静态变量重名,使用时会造成迷惑

  6. This private method is never called. Although it is possible that the method will be invoked through reflection, it is more likely that the method is never used, and should be removed.
    修改建议:删除该方法
    问题原因:
    这个私有方法没有被调用。虽然可能通过反射的方法将被调用,更可能从未使用过,应该被删除。

  7. This method calls equals(Object) on two references of different class types and analysis suggests they will be to objects of different classes at runtime. Further, examination of the equals methods that would be invoked suggest that either this call will always return false, or else the equals method is not be symmetric (which is a property required by the contract for equals in class Object).
    修改建议:
    去除这种无意义的判断
    问题原因:
    两个不同类型实例通过equals方法,通常情况下都会判断为非相同对象,其返回值也将始终为false。
    例如,调用string的equals方法比较double类型,永远都会返回false,如果把这个作为逻辑判断是没有意义的

  8. 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.
    修改建议:使用StringBuilder/StringBuffer
    问题原因:
    在循环里使用字符串连接,效率低
  9. A reference value which is null on some exception control path is dereferenced here. This may lead to a NullPointerException when the code is executed. Note that because SpotBugs currently does not prune infeasible exception paths, this may be a false warning.
    Also note that SpotBugs considers the default case of a switch statement to be an exception path, since the default case is often infeasible.
    修改建议:对引用对象进行判空
    问题原因:
    代码调用时,遇到异常分支,可能造成一个对象没有获得赋值依旧保持NULL空指针。接下来如果对这个对象有引用,可能造成NullPointerException空指针异常。
  10. A String function is being invoked and “.” or “|” is being passed to a parameter that takes a regular expression as an argument. Is this what you intended? For example
    – s.replaceAll(“.”, “/”) will return a String in which every character has been replaced by a ‘/’ character
    – s.split(“.”) always returns a zero length array of String
    – “ab|cd”.replaceAll(“|”, “/”) will return “/a/b/|/c/d/”
    – “ab|cd”.split(“|”) will return array with six (!) elements: [, a, b, |, c, d]
    修改建议:
    在前面加上“\”转义符。
    问题原因:
    String的split方法传递的参数是正则表达式,正则表达式本身用到的字符需要转义,如:句点符号“.”,美元符号“$”,乘方符号“^”,大括号“{}”,方括号“[]”,圆括号“()” ,竖线“|”,星号“*”,加号“+”,问号“?”等等,这些需要在前面加上“\”转义符。
  11. There is a branch of statement that, if executed, guarantees that a null value will be dereferenced, which would generate a NullPointerException when the code is executed. Of course, the problem might be that the branch or statement is infeasible and that the null pointer exception can’t ever be executed; deciding that is beyond the ability of SpotBugs.
    修改建议:
    判断header是否为null或使用try…catch…finally。
    问题原因:可能存在空引用
  12. This method call passes a null value for a non-null method parameter. Either the parameter is annotated as a parameter that should always be non-null, or analysis has shown that it will always be dereferenced.
    修改建议:赋予函数参数默认值。
    问题原因:传递了一个空值给函数参数
  13. The return value of this method should be checked. One common cause of this warning is to invoke a method on an immutable object, thinking that it updates the object. For example, in the following code fragment,
    String dateString = getHeaderField(name);
    dateString.trim();
    the programmer seems to be thinking that the trim() method will update the String referenced by dateString. But since Strings are immutable, the trim() function returns a new String value, which is being ignored here. The code should be corrected to:
    String dateString = getHeaderField(name);
    dateString = dateString.trim();
    修改建议:定义变量接收方法的返回值
    问题原因:忽略了该方法的返回值
  14. This method accesses the value of a Map entry, using a key that was retrieved from a keySet iterator. It is more efficient to use an iterator on the entrySet of the map, to avoid the Map.get(key) lookup.
    修改建议:遍历entry(桶)然后直接从entry得到value
    问题原因:
    很多人都这样遍历Map,没错,但是效率很低,先一个一个的把key遍历,然后在根据key去查找value,这不是多此一举么,为什么不遍历entry(桶)然后直接从entry得到value呢?它们的执行效率大概为1.5:1
  15. This code creates an exception (or error) object, but doesn’t do anything with it. For example, something like

    if (x < 0) {
        new IllegalArgumentException("x must be nonnegative");
    }
    It was probably the intent of the programmer to throw the created exception:
    
    if (x < 0) {
        throw new IllegalArgumentException("x must be nonnegative");
    }
    

    修改建议:将创建的异常抛出
    问题原因:创建了一个异常对象,但是没有对它做任何操作

  16. Using the java.lang.String(String) constructor wastes memory because the object so constructed will be functionally indistinguishable from the String passed as a parameter. Just use the argument String directly.
    修改建议:直接使用其参数
    问题原因:这里调用了String的构造函数来新建一个字符串,浪费内存

  17. This code contains a sequence of calls to a concurrent abstraction (such as a concurrent hash map). These calls will not be executed atomically.
    修改建议:使用putIfAbsent()保证操作是原子级的
    问题原因:在多线程访问的情况下,它是不安全的

  18. A value is checked here to see whether it is null, but this value can’t be null because it was previously dereferenced and if it were null a null pointer exception would have occurred at the earlier dereference. Essentially, this code and the previous dereference disagree as to whether this value is allowed to be null. Either the check is redundant or the previous dereference is erroneous
    修改建议:在使用变量之前先判断其是否为null
    问题原因:出现该bug有两种情况,多余的null检查或者没有进行null值检查。

  19. As the JavaDoc states, DateFormats are inherently unsafe for multithreaded use. The detector has found a call to an instance of DateFormat that has been obtained via a static field. This looks suspicious.
    修改建议:使用ThreadLocal: 每个线程都将拥有自己的SimpleDateFormat对象副本。
    问题原因:SimpleDateFormat不是线程安全的


版权声明:本文为fbb1995原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。