一、入门背景
近来公司安全工程师利用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
接口),都可以使用作为资源。
三、新旧写法对比
- 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();
}
}
}
- 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();
}
}
}
四、使用小结
- 自动关闭资源的try语句相当于包含了隐式的finally块(用于关闭资源),因此这个try语句可以既没有catch块,也没有finally块。
- 被自动关闭的资源必须实现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;
}
- Java7几乎把所有的“资源类”(包括文件IO的各种类,JDBC编程的Connection、Statement等接口……)进行了改写,改写后的资源类都实现了AutoCloseable或Closeable接口
- Java7新增的自动关闭资源的try语句允许在try关键字后紧跟一对圆括号,里面可以声明、初始化一个或多个资源,此处的资源指的是那些必须在程序结束时显示关闭的资源(数据库连接、网络连接等),try语句会在该语句结束时自动关闭这些资源。
- 被关闭的资源必须放在try语句后的圆括号中声明、初始化。如果程序有需要自动关闭资源的try语句后可以带多个catch块和一个finally块。