就像在标准 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 } }