一、入门背景

近来公司安全工程师利用VCG漏洞扫描工具,对开发接近尾声的项目进行安全扫描。长长扫描结果列表,对于java服务端的程序员真是一件苦差事。为什么呢?因为这个工具会出现扫描误报情况,比如try-with-resources用法对应代码没有finally语句块,结果是处处报standard:unsafe code …漏洞问题,意思是:未使用finally语句块释放资源,可能使系统出现资源不足的问题。

二、什么是try-with-resources

try-with-resources 是 JDK 7 中一个新的异常处理机制,它能够很容易(优雅)地关闭在 try-catch 语句块中使用的资源。所谓的资源(resource)是指在程序完成后,必须关闭的对象。try-with-resources 语句确保了每个资源在语句结束时关闭。所有实现了 java.lang.AutoCloseable 接口(或 java.io.Closeable接口),都可以使用作为资源。

三、新旧写法对比
  1. JDK7以前显示关闭资源:资源的显示关闭放在finally语句块中
public static void main(String[] args) throws IOException {
        InputStream input = null;
        try{
            input = new FileInputStream("d:\\hello.txt");
            int data = input.read();
            while(data != -1){
                System.out.print((char) data);
                data = input.read();
            }
        } finally {
            if(input != null){
                input.close();
            }
        }
    }
  1. JDK7及以后可自动关闭资源:可以不出现finally语句块
public static void main(String[] args) throws IOException {
        try (FileInputStream input = new FileInputStream("d:\\hello.txt")) {
            int data = input.read();
            while (data != -1) {
                System.out.print((char) data);
                data = input.read();
            }
        }
    }
四、使用小结
  1. 自动关闭资源的try语句相当于包含了隐式的finally块(用于关闭资源),因此这个try语句可以既没有catch块,也没有finally块。
  2. 被自动关闭的资源必须实现Closeable或AutoCloseable接口。(Closeable是AutoCloseable的子接口,Closeable接口里的close()方法声明抛出了IOException,;AutoCloseable接口里的close()方法声明抛出了Exception)
    源码 Closeable
public interface Closeable extends AutoCloseable {
    public void close() throws IOException;
}

源码 AutoCloseable

public interface AutoCloseable {
    void close() throws Exception;
}
  1. Java7几乎把所有的“资源类”(包括文件IO的各种类,JDBC编程的Connection、Statement等接口……)进行了改写,改写后的资源类都实现了AutoCloseable或Closeable接口
  2. Java7新增的自动关闭资源的try语句允许在try关键字后紧跟一对圆括号,里面可以声明、初始化一个或多个资源,此处的资源指的是那些必须在程序结束时显示关闭的资源(数据库连接、网络连接等),try语句会在该语句结束时自动关闭这些资源。
  3. 被关闭的资源必须放在try语句后的圆括号中声明、初始化。如果程序有需要自动关闭资源的try语句后可以带多个catch块和一个finally块。