异常处理机制——try-with-resources

Try-with-resources是java7中一个新的异常处理机制,能够很容易地关闭在try-catch语句块中使用的资源。

一、利用Try-Catch-Finally管理资源(旧的代码风格)

在java7以前,程序中使用的资源需要被明确地关闭

读取文件:

01 private static void printFile() throws IOException {
02     InputStream input = null;
03  
04     try {
05         input = new FileInputStream("file.txt");
06  
07         int data = input.read();
08         while(data != -1){
09             System.out.print((char) data);
10             data = input.read();
11         }
12     finally {
13         if(input != null){
14             input.close();
15         }
16     }
17 }

正如你所看到的,try语句块中有3个地方会抛出异常,finally语句块中有一个地方会出异常。

假设try语句块抛出一个异常,然后finally语句块被执行。同样假设finally语句块也抛出了一个异常。那么,即使try语句块中抛出的异常与异常传播更相关,最终还是finally语句块中抛出的异常会根据调用栈向外传播

在java7中,对于上面的例子可以用try-with-resource 结构这样写:

01 private static void printFileJava7() throws IOException {
02  
03     try(FileInputStream input = new FileInputStream("file.txt")) {
04  
05         int data = input.read();
06         while(data != -1){
07             System.out.print((char) data);
08             data = input.read();
09         }
10     }
11 }

注意方法中的第一行:

1 try(FileInputStream input = new FileInputStream("file.txt")) {

这就是try-with-resource 结构的用法。FileInputStream 类型变量就在try关键字后面的括号中声明。而且一个FileInputStream 类型被实例化并被赋给了这个变量。

当try语句块运行结束时,FileInputStream 会被自动关闭。这是因为FileInputStream 实现了java中的java.lang.AutoCloseable接口。所有实现了这个接口的类都可以在try-with-resources结构中使用。

当try-with-resources结构中抛出一个异常,同时FileInputStreami被关闭时(调用了其close方法)也抛出一个异常,try-with-resources结构中抛出的异常会向外传播,而FileInputStreami被关闭时抛出的异常被抑制了。这与文章开始处利用旧风格代码的例子(在finally语句块中关闭资源)相反。

二、使用多个资源

你可以在块中使用多个资源而且这些资源都能被自动地关闭。下面是例子:

01 private static void printFileJava7() throws IOException {
02  
03     try(  FileInputStream  input = new FileInputStream("file.txt");
04           BufferedInputStream bufferedInput = new BufferedInputStream(input)
05     ) {
06  
07         int data = bufferedInput.read();
08         while(data != -1){
09             System.out.print((char) data);
10             data = bufferedInput.read();
11         }
12     }
13 }

上面的例子在try关键字后的括号里创建了两个资源——FileInputStream 和BufferedInputStream。

当程序运行离开try语句块时,这两个资源都会被自动关闭。

这些资源将按照他们被创建顺序的逆序来关闭。首先BufferedInputStream 会被关闭,然后FileInputStream会被关闭。

三、自定义AutoClosable 实现

这个try-with-resources结构里不仅能够操作java内置的类。你也可以在自己的类中实现java.lang.AutoCloseable接口,然后在try-with-resources结构里使用这个类。

AutoClosable 接口仅仅有一个方法close(),接口定义如下:

1 public interface AutoClosable {
2  
3     public void close() throws Exception;
4 }

任何实现了这个接口的方法都可以在try-with-resources结构中使用。下面是一个简单的例子:

01 public class MyAutoClosable implements AutoCloseable {
02  
03     public void doIt() {
04         System.out.println("MyAutoClosable doing it!");
05     }
06  
07     @Override
08     public void close() throws Exception {
09         System.out.println("MyAutoClosable closed!");
10     }
11 }

doIt()是方法不是AutoClosable 接口中的一部分,之所以实现这个方法是因为我们想要这个类除了关闭方法外还能做点其他事。

下面是MyAutoClosable 在try-with-resources结构中使用的例子:

1 private static void myAutoClosable() throws Exception {
2  
3     try(MyAutoClosable myAutoClosable = new MyAutoClosable()){
4         myAutoClosable.doIt();
5     }
6 }

当方法myAutoClosable.doIt()被调用时,下面是打印到System.out的输出:

1 MyAutoClosable doing it!
2 MyAutoClosable closed!

通过上面这些你可以看到,不论try-catch中使用的资源是自己创造的还是java内置的类型,try-with-resources都是一个能够确保资源能被正确地关闭的强大方法。

四、 try-with-resources 在 JDK 9 中的改进

如果你已经有一个资源是 final 或等效于 final 变量,您可以在 try-with-resources 语句中直接使用该变量,而无需在 try-with-resources 语句中声明一个新变量。


例如:给定资源的声明

// A final resource
final Resource resource1 = new Resource("resource1");
// An effectively final resource
Resource resource2 = new Resource("resource2");

老方法编写代码来管理这些资源是类似的:

// Original try-with-resources statement from JDK 7 or 8
try (Resource r1 = resource1;
     Resource r2 = resource2) {
    // Use of resource1 and resource 2 through r1 and r2.
}

而新方法可以是

// New and improved try-with-resources statement in JDK 9
try (resource1;
     resource2) {
    // Use of resource1 and resource 2.
}

让我们一起遨游在代码的海洋里!
1. 什么是 Java 异常? Java 异常是指程序执行期间可能发生的错误或异常情况,例如除以零、数组越界、空指针引用等。当这些异常发生时,Java 虚拟机会抛出一个异常对象,并且程序的执行流程将被中断。 2. Java 异常处理机制有哪些关键字和语句? Java 异常处理机制包括以下关键字和语句: - try:用于包含可能会抛出异常的代码块。 - catch:用于捕获指定类型的异常,并在捕获到异常时执行相应的处理代码。 - finally:用于包含无论是否发生异常都需要执行的代码块。 - throw:用于抛出指定的异常对象。 - throws:用于声明可能会抛出指定类型异常的方法。 3. Java 中的异常分为哪几类? Java 中的异常分为两大类:Checked Exception 和 Unchecked Exception。 Checked Exception 是指在编译时就能够检查出来的异常,例如 IOException、ClassNotFoundException 等。程序必须显式地处理这些异常,否则编译不通过。 Unchecked Exception 是指在运行时才能检查出来的异常,例如 NullPointerException、ArrayIndexOutOfBoundsException 等。程序可以选择处理这些异常,但不处理也不会导致编译错误。 4. 请简要说明 try-catch-finally 的执行流程。 当程序执行到 try 块时,Java 会尝试执行其中的代码。如果在 try 块中抛出了异常,则会将异常对象传递给 catch 块进行处理。catch 块会匹配异常类型,如果匹配成功,则执行相应的处理代码。如果 catch 块处理完异常后,程序需要继续执行,则会执行 finally 块中的代码。如果 finally 块中也抛出了异常,则该异常会覆盖 try 或 catch 块中的异常。 如果 try 块中没有抛出异常,则 catch 块不会被执行。如果 finally 块中抛出异常,则该异常会覆盖 try 块中的异常。 5. 什么是异常链? 异常链是指在处理异常时,将一个异常对象作为另一个异常的原因,并将它们组合成一个异常链。这样做的好处是,在抛出异常时可以同时传递多个异常信息,从而更加清晰地表示异常发生的原因。 6. 请简要说明 try-with-resources 的作用和使用方法。 try-with-resourcesJava 7 中引入的语法,用于自动关闭实现了 AutoCloseable 接口的资源。在 try 块中声明需要使用的资源,Java 会在 try 块执行完毕后自动关闭这些资源,无需手动调用 close 方法。 try-with-resources 的语法如下: ``` try (Resource1 r1 = new Resource1(); Resource2 r2 = new Resource2()) { // 使用资源 } catch (Exception e) { // 处理异常 } ``` 7. 请简要说明 Java 中的文本 IO。 Java 中的文本 IO 主要包括两种类:Reader 和 Writer。Reader 用于读取字符流,而 Writer 用于写入字符流。 Java 中常用的 Reader 类包括 InputStreamReader、FileReader 和 BufferedReader,常用的 Writer 类包括 OutputStreamWriter、FileWriter 和 BufferedWriter。这些类提供了各种方法来读取和写入字符流,并且可以处理多种编码格式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值