就像在标准 try 代码块中添加 catch 代码块一样,您也可以在带有资源的 try 代码块中添加 catch 代码块。如果在带有资源的 try 代码块的 try 代码块中抛出异常,catch 代码块就会捕获异常,就像使用标准 try 结构一样。例如:
package com.hxstrive.jdk7.try_with_resources;
/**
* JDK7 新特性 try-with-resources
* @author hxstrive.com
*/
public class TryWithResourcesDemo8 {
static class MyResource implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("close");
}
public void doSomething(String message) {
System.out.println("doSomething() message=" + message.toUpperCase());
}
}
public static void main(String[] args) {
try (MyResource resource = new MyResource()) {
resource.doSomething("hello");
resource.doSomething(null);
} catch (Exception e) {
e.printStackTrace();
}
//结果:
//doSomething() message=HELLO
//close
//java.lang.NullPointerException: Cannot invoke "String.toUpperCase()" because "message" is null
}
}在进入 catch 代码块之前,try-with-resources 结构会尝试关闭 try 代码块中打开的资源。如果在尝试关闭其中一个资源时出现异常,这些异常将可以通过 catch 代码块中的 getSuppressed() 方法获取。下面是一个附带 catch 代码块的 Java try-with-resources 代码块示例:
package com.hxstrive.jdk7.try_with_resources;
import java.util.Arrays;
/**
* JDK7 新特性 try-with-resources
* @author hxstrive.com
*/
public class TryWithResourcesDemo9 {
static class MyResource implements AutoCloseable {
@Override
public void close() throws Exception {
throw new Exception("MyResource.close error");
}
public void doSomething(String message) {
System.out.println("doSomething() message=" + message.toUpperCase());
}
}
public static void main(String[] args) {
try (MyResource resource = new MyResource()) {
resource.doSomething("hello");
resource.doSomething(null);
} catch (Exception e) {
System.out.println(Arrays.toString(e.getSuppressed()));
e.printStackTrace();
}
//结果:
//doSomething() message=HELLO
//[java.lang.Exception: MyResource.close error]
//java.lang.NullPointerException: Cannot invoke "String.toUpperCase()" because "message" is null
}
}在上面的示例中,MyResource 的 doSomething() 方法参数为 null 时,try 代码块和资源关闭均会抛出异常。从doSomething() 中抛出的异常会在 catch 块中捕获,其 getSuppressed() 方法会返回一个数组,其中包含试图关闭资源时抛出的异常。
如果只有在试图关闭资源时才会抛出异常,则 catch 块也会捕获该异常。该异常的 getSuppressed() 方法将返回一个空数组,因为没有异常被抑制。例如:
package com.hxstrive.jdk7.try_with_resources;
import java.util.Arrays;
/**
* JDK7 新特性 try-with-resources
* @author hxstrive.com
*/
public class TryWithResourcesDemo10 {
static class MyResource implements AutoCloseable {
@Override
public void close() throws Exception {
throw new Exception("MyResource.close error");
}
public void doSomething(String message) {
System.out.println("doSomething() message=" + message.toUpperCase());
}
}
public static void main(String[] args) {
try (MyResource resource = new MyResource()) {
resource.doSomething("hello");
} catch (Exception e) {
System.out.println(Arrays.toString(e.getSuppressed()));
e.printStackTrace();
}
//结果:
//doSomething() message=HELLO
//[]
//java.lang.Exception: MyResource.close error
}
}