FindBugs问题集锦

1. Unread public/protected field

This field is never read. The field is public or protected, so perhaps it is intended to be used with classes not seen as part of the analysis. If not, consider removing it from the class.

  • 原因
    Public/protected字段在本类中未被使用
  • 解决办法
    ① 如果类中字段被其它类引用,则需要在本类中也进行引用;
    ② 如果类中字段仅被本类引用,字段访问权限改为private;
    ③ 如果类中字段没有被本类,也没有被其它类引用,考虑移除。

2. Incorrect lazy initialization of static field

This method contains an unsynchronized lazy initialization of a non-volatile static field. Because the compiler or processor may reorder instructions, threads are not guaranteed to see a completely initialized object, if the method can be called by multiple threads. You can make the field volatile to correct the problem.

  • 原因
    存在延迟初始化的线程不安全的static字段
  • 解决办法
    将该字段改为volatile的

3. Method may fail to clean up stream or resource on checked exception

This method may fail to clean up (close, dispose of) a stream, database object, or other resource requiring an explicit cleanup operation.
In general, if a method opens a stream or other resource, the method should use a try/finally block to ensure that the stream or resource is cleaned up before the method returns.

  • 原因
    流或者源可能关闭或清理失败
  • 解决办法
    当存在流或者源等使用时(如:FileInputStream),应该将使用部分使用try/finally块包围,在finally中关闭资源.
  • 注意
    流/资源类初始化后,应紧跟try/catch块,否则findbugs还会判定有问题

4. Method may fail to close stream

The method creates an IO stream object, does not assign it to any fields, pass it to other methods that might close it, or return it, and does not appear to close the stream on all paths out of the method. This may result in a file descriptor leak. It is generally a good idea to use a finally block to ensure that streams are closed.

  • 原因
    与上一个类似,未正确关闭流
  • 解决办法
    流关闭时,需要在finall中关闭,且关闭前需要做非空判断

5. Possible null pointer dereference in method on exception path

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 FindBugs currently does not prune infeasible exception paths, this may be a false warning.
Also note that FindBugs considers the default case of a switch statement to be an exception path, since the default case is often infeasible.

  • 原因
    在可能存在空指针异常
  • 解决办法
    例如:在流关闭时,需要先判断其为非空再关闭
    if (stream != null) { stream.close();}

6. Reliance on default encoding

Found a call to a method which will perform a byte to String (or String to byte) conversion, and will assume that the default platform encoding is suitable. This will cause the application behaviour to vary between platforms. Use an alternative API and specify a charset name or Charset object explicitly.

  • 原因
    将byte转为String类型未指定编码方式
  • 解决办法
    指定编码方式
    如:ByteArrayOutputStream out = new ByteArrayOutputStream();
    ……
    out.toString();
    修改为 : out.toString(“UTF-8”);

7. Call to static DateFormat

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 suspicous.

  • 原因
    DateForma及其子类线程不安全
  • 解决办法
    ① 将SimpleDateFormat定义为局部变量(非static的全局变量),如:
    new SimpleDateFormat(“yyyyMMdd”).format(data);
    ② 同步等解决线程安全的方法

8. Method ignores results of InputStream.read()

This method ignores the return value of one of the variants of java.io.InputStream.read() which can return multiple bytes. If the return value is not checked, the caller will not be able to correctly handle the case where fewer bytes were read than the caller requested. This is a particularly insidious kind of bug, because in many programs, reads from input streams usually do read the full amount of data requested, causing the program to fail only sporadically.

  • 原因
    InputStream.read()忽略读取的返回值,不对该返回值进行判断,可能造成数据读取不完整等现象。
  • 解决办法
    获取read()的返回值(一般为读取的字节数),并对返回值进行判断,根据判断结果决定后续流写的情况(读多少字节,写多少字节,直至结束)。

例:

InputStream in = blob.getBinaryStream();
in.read(byte1);

修改为:

InputStream in = blob.getBinaryStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] temp = new byte[1024];

int hasRead = 0;
while ((hasRead = in.read(temp)) != -1) {
out.write(temp, 0, hasRead);
}
return out.toByteArray();

9. Boxing/unboxing to parse a primitive

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.

  • 原因
    自动装箱拆箱,效率低,建议使用parseXXX方法
  • 解决办法
    例如:Long.valueOf(“123L”) ;(查看源码中valueOf()方法内调用了parseXXX方法)
    修改为:Long.parseLong(“123L”);

10. Exception created and dropped rather than thrown

This code creates an exception (or error) object, but doesn’t do anything with it.

  • 原因
    创建了Exception, 但未作任何操作,需要进行throw
  • 解决办法
    例如:new Exception(“Test failed”);
    修改为:throw new Exception(“Test failed”);

11. 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.

  • 原因
    循环中拼接字符串,使用了+,性能低。因为+操作每次会new一个新的String对象
  • 解决办法
    建议使用StringBuffer(线程安全)/ StringBuilder(非线程安全,单线程中使用,效率高)

12. Possible null pointer dereference due to return value of called method

The return value from a method is dereferenced without a null check, and the return value of that method is one that should generally be checked for null. This may lead to a NullPointerException when the code is executed.

  • 原因
    未进行判空,可能造成空指针异常
  • 解决办法
    对可能抛空指针异常的对象,使用之前先进行非空判断(注意:判断需要紧跟该对象使用,否则findbugs可能无法识别)
    例如:if (source != null) {Class sourceClass = source.getClass();}

13. equals method overrides equals in superclass and may not be symmetric

This class defines an equals method that overrides an equals method in a superclass. Both equals methods methods use instanceof in the determination of whether two objects are equal. This is fraught with peril, since it is important that the equals method is symmetrical (in other words, a.equals(b) == b.equals(a)). If B is a subtype of A, and A’s equals method checks that the argument is an instanceof A, and B’s equals method checks that the argument is an instanceof B, it is quite likely that the equivalence relation defined by these methods is not symmetric.

  • 原因
    覆写父类的equals()方法可能是非对称的
  • 解决办法
    ① 自己实现覆写equals()方法
    ② 笔者这里是由于使用了lombok的@Data注解自带覆写equals()方法
    为简单的属性类,可使用@EqualsAndHashCode(callSuper = true)解决

14. An increment to a volatile field isn’t atomic

This code increments a volatile field. Increments of volatile fields aren’t atomic. If more than one thread is incrementing the field at the same time, increments could be lost.

  • 原因
    自增操作对于volatile字段不是原子操作,非线程安全的
  • 解决办法
    自增操作可以使用相应原子类实现,如:
    private volatile int num = 0;
    num ++;
    改为:
    private AtomicInteger num = new AtomicInteger(0);
    num.getAndIncrement();
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值