关于try-with-resource的 输入输出流自动关闭

最近在做代码审核的时候,审核工具提示我将 try-catch-finally 给替换掉,而且根据公司相关要求,该提示的级别还不低,不改不予通过.
先看看代码吧:

FileReader fr = null;  
BufferedReader br = null;

try {
    fr = new FileReader(fileName);
    br = new BufferedReader(fr);
    return br.readLine();
} catch (Exception e) {
    log.error("error:{}", e);
} finally {
  if (br != null) {
    try {
      br.close();
    } catch(IOException e){
      log.error("error:{}", e);
    }
  }

  if (fr != null ) {
    try {
      br.close();
    } catch(IOException e){
      log.error("error:{}", e);
    }
  }
}

审核工具给出的意见是 替换为:

try (
    FileReader fr = new FileReader(fileName);
    BufferedReader br = new BufferedReader(fr)
  ) {
    return br.readLine();
}catch (Exception e) {
    log.error("error:{}", e);
}

或者是:

try (
    BufferedReader br = new BufferedReader(new FileReader(fileName))
  ) { 
    // no need to name intermediate resources if you don't want to
    return br.readLine();
}
catch (Exception e) { 
    log.error("error:{}", e);
}

对比代码,不难发现,输入输出流的关闭存在着差异.难道输入输出流不用关闭了吗? 带着这个问题看看源代码,发现

public class FileInputStream extends InputStream{}

public abstract class InputStream implements Closeable {}


/**
 * A {@code Closeable} is a source or destination of data that can be closed.
 * The close method is invoked to release resources that the object is
 * holding (such as open files).
 *
 * @since 1.5
 */
public interface Closeable extends AutoCloseable {}


/**
 * An object that may hold resources (such as file or socket handles)
 * until it is closed. The {@link #close()} method of an {@code AutoCloseable}
 * object is called automatically when exiting a {@code
 * try}-with-resources block for which the object has been declared in
 * the resource specification header. This construction ensures prompt
 * release, avoiding resource exhaustion exceptions and errors that
 * may otherwise occur.
 *
 * @apiNote
 * 

It is possible, and in fact common, for a base class to * implement AutoCloseable even though not all of its subclasses or * instances will hold releasable resources. For code that must operate * in complete generality, or when it is known that the {@code AutoCloseable} * instance requires resource release, it is recommended to use {@code * try}-with-resources constructions. However, when using facilities such as * {@link java.util.stream.Stream} that support both I/O-based and * non-I/O-based forms, {@code try}-with-resources blocks are in * general unnecessary when using non-I/O-based forms. * * @author Josh Bloch * @since 1.7 */ public interface AutoCloseable {}

AutoCloseable 顾名思义, 自动关闭流. 从注释中我们可以发现,实现了AutoCloseable并在try()中声明的对象,当try-with-resource代码块执行完的时候,会自动调用close()方法.
注意: 一个 try-with-resources 语句可以像普通的 try 语句那样有 catch 和 finally 块。在try-with-resources 语句中, 任意的 catch 或者 finally 块都是在声明的资源被关闭以后才运行。

你可能感兴趣的:(Java基础)