sonar常见缺陷和修改

1. Resources should be closed

IO资源应该在使用后关闭。在try语句中使用了Connections, streams, files等,这些类实现了Closeable 或者AutoCloseable接口,必须在finally块中关闭,否则,如果出现异常就可能无法关闭。对于实现了AutoCloseable接口的类,最好使用“try-with-resource”语句来自动关闭。如果不能正确地关闭资源,就会导致资源泄漏,这可能会导致应用程序甚至整个系统的崩溃。

关于IO资源的处理问题,以下比较三种解决方案。

  • close()放在try块中
  • close()放在finally块中
  • 使用try-with-resource语句

close()放在try块中

//close() is in try clause
try {
    PrintWriter out = new PrintWriter(
            new BufferedWriter(
            new FileWriter("out.txt", true)));
    out.println("the text");
    out.close();
} catch (IOException e) {
    e.printStackTrace();
}

这种方式容易造成IO资源的泄露,因为对于IO资源来说不管操作的结果如何都必须关闭。

close()放在finally块中

//close() is in finally clause
PrintWriter out = null;
try {
    out = new PrintWriter(
        new BufferedWriter(
        new FileWriter("out.txt", true)));
    out.println("the text");
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (out != null) {
        out.close();
    }

这种方式在JDK1.7之前,推荐使用这种方式,但是,这种方式还是有问题,因为,在try块和finally块中可能都会发生Exception。

使用try-with-resource语句

//try-with-resource statement
try (PrintWriter out2 = new PrintWriter(
            new BufferedWriter(
            new FileWriter("out.txt", true)))) {
    out2.println("the text");
} catch (IOException e) {
    e.printStackTrace();
}

这种方式可能是最好的,Java官方推荐使用这种方式,但是,使用的前提是你的jdk版本在1.7以上。

因为不管什么情况下(异常或者非异常)资源都必须关闭,在jdk1.6之前,应该把close()放在finally块中,以确保资源的正确释放。

如果使用jdk1.7以上的版本,推荐使用try-with-resources语句。


2. "InterruptedException" should not be ignored

在代码中不应该忽略中断异常,只在日志中打印异常日志,就像“忽略”一样。抛出中断异常会清除线程的中断状态,因此如果异常处理不当,那么线程被中断的信息将会丢失。相反,中断应该被重新抛出——立即或者在清理方法的状态之后——或者应该通过调用Thread.interrupt()来重新中断线程,即使这是单线程的应用程序。任何其他的操作过程都有延迟线程关闭的风险,并且丢失了线程被中断的信息——线程很可能没有完成它的任务。

类似地,也应该传播ThreadDeath异常。根据它的JavaDoc:

如果ThreadDeath异常被一个方法捕获,那么它被重新抛出是很重要的,这样线程就会结束。

不符合要求的代码如下:

public void run () {
  try {
    while (true) {
      // do stuff
    }
  }catch (InterruptedException e) { // Noncompliant; logging is not enough
    LOGGER.log(Level.WARN, "Interrupted!", e);
  }
}

 catch块中只是打印了异常日志,相当于忽略了这个异常。

处理建议为抛出异常:

public void run () {
  try {
    while (true) {
      // do stuff
    }
  }catch (InterruptedException e) {
    LOGGER.log(Level.WARN, "Interrupted!", e);
    // Restore interrupted state...
    Thread.currentThread().interrupt();
  }
}

catch块中记录中断状态之后将线程中断,正确的处理了中断异常。

3.Null pointers should not be dereferenced/accessed.

对值为null的指针调用任何方法,就会引发空指针异常(java.lang.NullPointerException)。在最好的情况下,这样的异常会导致程序终止。在最坏的情况下,它可能暴露出对攻击者有用的调试信息,或者它可能允许攻击者绕过安全措施。

以下为不符合要求的代码举例:

public boolean isNameEmpty() {
  return getName().length() == 0; // Noncompliant; the result of getName() could be null, but isn't null-checked
}
 
Connection conn = null;
Statement stmt = null;
try{
  conn = DriverManager.getConnection(DB_URL,USER,PASS);
  stmt = conn.createStatement();
  // ...
 
}catch(Exception e){
  e.printStackTrace();
}finally{
  stmt.close();   // Noncompliant; stmt could be null if an exception was thrown in the try{} block
  conn.close();  // Noncompliant; conn could be null if an exception was thrown
}
 
private void merge(@Nonnull Color firstColor, @Nonnull Color secondColor){...}
 
public  void append(@CheckForNull Color color) {
    merge(currentColor, color);  // Noncompliant; color should be null-checked because merge(...) doesn't accept nullable parameters
}
 
void paint(Color color) {
  if(color == null) {
    System.out.println("Unable to apply color " + color.toString());  // Noncompliant; NullPointerException will be thrown
    return;
  }
  ...
}

4.Non-thread-safe fields should not be static

并不是标准Java库中的所有类都为线程安全的。多线程时,有些类很可能会在运行时引起数据问题或异常。

在Calendar,DateFormat,javax.xml.xpath.XPath或 javax.xml.validation.SchemaFactory生成静态的实例时会出问题。

缺陷举例:

public class MyClass {
  static private SimpleDateFormat format = new SimpleDateFormat("HH-mm-ss");  // Noncompliant
  static private Calendar calendar = Calendar.getInstance();  // Noncompliant
解决建议:
public class MyClass {
  private SimpleDateFormat format = new SimpleDateFormat("HH-mm-ss");
  private Calendar calendar = Calendar.getInstance();


你可能感兴趣的:(sonar)