Java try-with-resources语句
try-with-resources
语句是 Java 7 引入的一个特性,用于自动管理资源的关闭。这个特性确保了在 try
块执行完毕后,所有声明为资源的变量都会被自动关闭,即使发生异常也是如此。这不仅简化了代码,还减少了资源泄漏的风险。
try-with-resources基本语法:
try (ResourceType resource1 = new ResourceType(...);ResourceType resource2 = new ResourceType(...)) {// 使用资源的代码
} catch (ExceptionType1 e1) {// 处理异常
} catch (ExceptionType2 e2) {// 处理异常
} finally {// 可选的 finally 块
}
- 资源:必须实现
java.lang.AutoCloseable
接口(或其子接口java.io.Closeable
)。常见的资源包括文件流、数据库连接等,必须写在try后面的括号里。 - 多个资源:可以在
try
语句的小括号中声明多个资源,用分号分隔。
自动关闭机制:
当 try
块执行完毕后,无论是否抛出异常,所有声明的资源都会按照声明的逆序调用它们的 close
方法。如果一个资源的 close
方法抛出异常,而另一个资源的 close
方法也抛出异常,那么第二个异常会被抑制,并附加到第一个异常上。
示例代码:
以下是一个使用 try-with-resources
语句的示例,展示了如何读取一个文件并将其内容写入另一个文件。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class FileCopyExample {public static void main(String[] args) {try (FileInputStream fileIn = new FileInputStream("source.txt");FileOutputStream fileOut = new FileOutputStream("destination.txt")) {byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = fileIn.read(buffer)) != -1) {fileOut.write(buffer, 0, bytesRead);}// 可选:fileOut.flush(); 因为 try-with-resources 会在关闭时自动刷新} catch (IOException e) {e.printStackTrace();}}
}
详细说明:
-
资源声明:
- 在
try
语句的小括号中声明了两个资源:FileInputStream
和FileOutputStream
。 - 这些资源实现了
AutoCloseable
接口,因此可以在try-with-resources
语句中使用。
- 在
-
读取和写入数据:
- 定义了一个大小为 1024 字节的缓冲区数组
buffer
。 - 使用
while
循环从源文件source.txt
读取数据,并将数据写入目标文件destination.txt
。
- 定义了一个大小为 1024 字节的缓冲区数组
-
自动关闭:
- 当
try
块执行完毕后,fileIn
和fileOut
会自动关闭,不需要显式调用close
方法。 - 如果在读取或写入过程中抛出
IOException
,它会在catch
块中被捕获并处理。
- 当
注意事项:
- 资源顺序:资源的关闭顺序是按照它们在
try
语句中的声明顺序的逆序进行的。 - 异常处理:如果多个资源的
close
方法都抛出异常,后续的异常会被抑制,并附加到第一个异常上。可以通过getSuppressed()
方法获取这些抑制的异常。 - 可选的
finally
块:虽然try-with-resources
通常可以替代finally
块来关闭资源,但你仍然可以添加finally
块来执行其他清理工作。
抑制异常示例:
如果你需要处理多个资源关闭时可能抛出的异常,可以使用 Throwable.getSuppressed()
方法来获取这些异常。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class FileCopyExample {public static void main(String[] args) {try (FileInputStream fileIn = new FileInputStream("source.txt");FileOutputStream fileOut = new FileOutputStream("destination.txt")) {byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = fileIn.read(buffer)) != -1) {fileOut.write(buffer, 0, bytesRead);}} catch (IOException e) {e.printStackTrace();for (Throwable t : e.getSuppressed()) {t.printStackTrace();}}}
}
在这个示例中,如果 fileIn.close()
或 fileOut.close()
抛出异常,这些异常会被抑制,并通过 e.getSuppressed()
获取并在 catch
块中打印出来。这样可以更全面地处理所有可能发生的异常。
异常体系参考:Java 异常体系-CSDN博客