Java 7提供一个新的功能之一就是用于自动资源管理的try-with-resources
语句。
资源是一个在使用它完成程序后必须关闭的对象。例如,数据库连接的文件资源或JDBC资源或Socket连接资源。在Java 7之前,没有自动资源管理,程序员在完成工作后明确关闭资源。通常,它是在try-catch
语句的finally
块中完成的。当我们忘记关闭资源时,这种方法会导致内存泄漏和性能损失。
下面来看看一个伪代码片段来理解这个带有资源功能的java try。
在Java 7之前:
try{
//open resources like File, Database connection, Sockets etc
} catch (FileNotFoundException e) {
// Exception handling like FileNotFoundException, IOException etc
}finally{
// close resources
}
Java 7尝试使用资源实现:
try(// open resources here){
// use resources
} catch (FileNotFoundException e) {
// exception handling
}
// resources are closed as soon as try-catch block is executed.
让我们编写一个简单的程序来读取文件并使用Java 6或更早版本,以及使用Java 7 try-with-resources实现。
Java 6资源管理示例
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Java6ResourceManagement {
public static void main(String[] args) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("C://yiibai.com.txt"));
System.out.println(br.readLine());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)
br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
Java 7 try with resources示例
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Java7ResourceManagement {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader(
"C:/yiibai.com.txt"))) {
System.out.println(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Java try with resources优点
在java中使用try with resources
的一些好处是:
- 代码更易读,易于编写。
- 自动资源管理。
- 代码行数减少了。
- 不需要在
finally
块中关闭资源。可以在用分号分隔的try-with-resources
语句中打开多个资源。例如,可以编写以下代码:
try (BufferedReader br = new BufferedReader(new FileReader(
"C:/yiibai.com.txt"));
java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(FileSystems.getDefault().getPath("C:/yiibai.com.txt"), Charset.defaultCharset())) {
System.out.println(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
在try-with-resources
中打开多个资源时,它会以相反的顺序关闭它们以避免任何依赖性问题。
Java 7引入了一个新的接口java.lang.AutoCloseable
。要在try-with-resources
中使用任何资源,它必须实现AutoCloseable
接口,否则java编译器将抛出编译错误。
如下示例代码 -
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.FileSystems;
public class Java7ResourceManagement {
public static void main(String[] args) {
try (MyResource mr = new MyResource()) {
System.out.println("MyResource created in try-with-resources");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Out of try-catch block.");
}
static class MyResource implements AutoCloseable{
@Override
public void close() throws Exception {
System.out.println("Closing MyResource");
}
}
}
执行上面示例代码,得到以下结果 -
MyResource created in try-with-resources
Closing MyResource
Out of try-catch block.
从输出中可以清楚地看到,一旦try-catch
块完成,就会调用资源close
方法。
try with Resources异常
在异常的情况下,try-catch-finally
和try-with-resources
之间需要注意一个区别。
如果在try
块和finally
块中都抛出异常,则该方法返回finally
块中抛出的异常。
对于try-with-resources
,如果在try
块和try-with-resources
语句中抛出异常,则该方法返回try
块中抛出的异常。
为了更好地理解这种差异,请阅读以下示例代码。
public class Java7ResourceManagement {
public static void main(String[] args) throws Exception {
try {
tryWithResourceException();
} catch (Exception e) {
System.out.println(e.getMessage());
}
try {
normalTryException();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
private static void normalTryException() throws Exception {
MyResource mr = null;
try {
mr = new MyResource();
System.out.println("MyResource created in the try block");
if (true)
throw new Exception("Exception in try");
} finally {
if (mr != null)
mr.close();
}
}
private static void tryWithResourceException() throws Exception {
try (MyResource mr = new MyResource()) {
System.out.println("MyResource created in try-with-resources");
if (true)
throw new Exception("Exception in try");
}
}
static class MyResource implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("Closing MyResource");
throw new Exception("Exception in Closing");
}
}
}
执行上面示例代码,得到以下结果 -
MyResource created in try-with-resources
Closing MyResource
Exception in try
MyResource created in the try block
Closing MyResource
Exception in Closing
程序的输出证明了上面所说的差异。上面就是Java 7 try-with-resources的全部内容。