资源是一个程序利用后必须关闭的对象。 例如,用于数据库连接的文件资源或JDBC资源或套接字连接资源。 在Java7之前,没有自动资源管理,我们应该在我们的工作完成后明确地关闭资源。 通常,它是在try-catch语句的finally块中完成的。 当我们忘记关闭资源时,这种方法会导致内存泄漏和性能问题。
before 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 with resources implementation:
try(// open resources here){
// use resources
} catch (FileNotFoundException e) {
// exception handling
}
// resources are closed as soon as try-catch block is executed.
接下来分别看看Java6和Java7的简单例子:
Java 6 :
public class Java6ResourceManager {
public static void main (String[] args) {
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader("C:\\Users\\10944\\Desktop\\python.txt"));
System.out.println(bufferedReader.readLine());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bufferedReader != null) {
bufferedReader.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
Java 7:
public class Java7ResourceManager {
public static void main (String[] args) {
try (BufferedReader bufferedReader = new BufferedReader(new FileReader("C:\\Users\\10944\\Desktop\\python.txt"))) {
System.out.println(bufferedReader.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Java try with resources 的好处:
- 代码的可读性更好,更易于编写代码
- 自动化的资源管理
- 代码的行数被减少
- 不需要使用finally块来关闭资源
- 我们可以通过在try-with-resources中使用分号来间隔多个资源,例子如下:
try (BufferedReader br = new BufferedReader(new FileReader(
"C:\\python.txt"));
java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(FileSystems.getDefault().getPath("C:\\journaldev.txt"), Charset.defaultCharset())) {
System.out.println(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
7.当我们在try-with-resources中使用多个资源的时候,try-with-resources会在关闭时通过逆序的方式关闭,从而避免出现资源依赖的问题。
Java 7 介绍了一个新的接口:java.lang.AutoCloseable。任何资源在用于 try-with-resources 时,都需要实现这个接口,否则Java编译器会抛出编译问题。
以下是个简单的例子:
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模块完成,资源关闭的方法就会被调用。
Try with Resources Exceptions:
在异常的情况下,try-catch-finally 和 try-with-resources 是有不同的地方的。
如果一个异常在 try 块和 finally 块中被抛出,最终方法返回的将是在finally快块中抛出的异常。
而对 try-with-resources 而言,如果一个异常在 try 块和 try-with-resources 中被抛出,那么方法返回的将是在 try 中抛出的异常。
以下讲一个简单的例子:
public class Java7ResourceManagerDiff {
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 myResource = null;
try {
myResource = new MyResource();
System.out.println("MyResource created in block!");
if (true) {
throw new Exception("Exception in try block");
}
} finally {
if (myResource != null) {
myResource.close();
}
}
}
private static void tryWithResourceException () throws Exception{
try (MyResource myResource = new MyResource()) {
System.out.println("MyResource created in try-with block!");
if (true) {
throw new Exception("Exception in try block");
}
}
}
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 block!
Closing MyResource!
Exception in try block
MyResource created in block!
Closing MyResource!
Exception in Closing