Java try-with-resources
Java try-with-resources
在本教程中,我们将学习 try-with-resources 语句来自动关闭资源。
try-with-resources
语句在语句末尾自动关闭所有资源。资源是在程序结束时要关闭的对象。
它的语法是:
try (resource declaration) {
// use of the resource
} catch (ExceptionType e1) {
// catch block
}
从上面的语法可以看出,我们声明了try-with-resources
声明人,
- 在
try
中声明和实例化资源 子句。 - 指定和处理关闭资源时可能引发的所有异常。
注意: try-with-resources 语句关闭所有实现 AutoCloseable 接口的资源。
让我们举一个实现 try-with-resources
的例子 声明。
示例 1:try-with-resources
import java.io.*;
class Main {
public static void main(String[] args) {
String line;
try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
while ((line = br.readLine()) != null) {
System.out.println("Line =>"+line);
}
} catch (IOException e) {
System.out.println("IOException in try block =>" + e.getMessage());
}
}
}
如果未找到 test.txt 文件则输出。
IOException in try-with-resources block =>test.txt (No such file or directory)
如果找到 test.txt 文件则输出。
Entering try-with-resources block Line =>test line
在本例中,我们使用 BufferedReader 的实例 从 test.txt
读取数据 文件。
声明和实例化 BufferedReader try-with-resources
内 语句确保其实例关闭,无论 try
语句正常完成或抛出异常。
如果发生异常,可以使用异常处理块或 throws 关键字进行处理。
抑制的异常
在上面的例子中,可以从 try-with-resources
抛出异常 声明时:
- 文件
test.txt
找不到。 - 关闭
BufferedReader
对象。
try
也可以抛出异常 阻塞作为文件读取随时可能由于多种原因而失败。
如果 try
都抛出异常 块和 try-with-resources
语句,来自 try
的异常 块被抛出并且来自 try-with-resources
的异常 声明被禁止。
检索抑制的异常
在 Java 7 及更高版本中,可以通过调用 Throwable.getSuppressed()
来检索被抑制的异常 try
抛出的异常中的方法 块。
此方法返回所有抑制异常的数组。我们在 catch
中得到抑制的异常 块。
catch(IOException e) {
System.out.println("Thrown exception=>" + e.getMessage());
Throwable[] suppressedExceptions = e.getSuppressed();
for (int i=0; i<suppressedExceptions.length; i++) {
System.out.println("Suppressed exception=>" + suppressedExceptions[i]);
}
}
使用 try-with-resources 的优势
以下是使用 try-with-resources 的优点:
1。 finally 块不需要关闭资源
在 Java 7 引入这个特性之前,我们不得不使用 finally
块,确保资源关闭,避免资源泄漏。
这是一个类似于 示例 1 的程序 .但是,在这个程序中,我们使用 finally 块来关闭资源。
示例 2:使用 finally 块关闭资源
import java.io.*;
class Main {
public static void main(String[] args) {
BufferedReader br = null;
String line;
try {
System.out.println("Entering try block");
br = new BufferedReader(new FileReader("test.txt"));
while ((line = br.readLine()) != null) {
System.out.println("Line =>"+line);
}
} catch (IOException e) {
System.out.println("IOException in try block =>" + e.getMessage());
} finally {
System.out.println("Entering finally block");
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
System.out.println("IOException in finally block =>"+e.getMessage());
}
}
}
}
输出
Entering try block Line =>line from test.txt file Entering finally block
从上面的例子我们可以看出,finally
的使用 块清理资源使代码更复杂。
注意 try...catch
finally
中的块 也阻止?这是因为 IOException
也可能在关闭 BufferedReader
时发生 finally
中的实例 块,因此它也被捕获和处理。
try-with-resources
语句执行自动资源管理 .我们不需要显式关闭资源,因为 JVM 会自动关闭它们。这使得代码更具可读性和更容易编写。
2。 try-with-resources 与多个资源
我们可以在 try-with-resources
中声明多个资源 用分号 ;
分隔语句
示例 3:尝试使用多个资源
import java.io.*;
import java.util.*;
class Main {
public static void main(String[] args) throws IOException{
try (Scanner scanner = new Scanner(new File("testRead.txt"));
PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
while (scanner.hasNext()) {
writer.print(scanner.nextLine());
}
}
}
}
如果这个程序执行没有产生任何异常,Scanner
对象从 testRead.txt
中读取一行 文件并将其写入新的 testWrite.txt
文件。
当进行多个声明时,try-with-resources
语句以相反的顺序关闭这些资源。在本例中,PrintWriter
先关闭对象,然后关闭 Scanner
对象已关闭。
Java 9 try-with-resources 增强
在 Java 7 中,对 try-with-resources
有一个限制 陈述。资源需要在其块中本地声明。
try (Scanner scanner = new Scanner(new File("testRead.txt"))) {
// code
}
如果我们在 Java 7 中在块之外声明资源,则会产生错误消息。
Scanner scanner = new Scanner(new File("testRead.txt"));
try (scanner) {
// code
}
为了处理这个错误,Java 9 改进了 try-with-resources
声明,以便即使没有在本地声明资源的引用,也可以使用它。上面的代码现在将执行,没有任何编译错误。
java