现在让我们用Java 7 的try-with-resource构成部署相同程序。这样,我们就需要一个新的资源-NewResource。在Java7中,引入了一个新的界面java.lang.AutoCloseable。那些资源需要被关闭的资源部署了这个界面。所有旧式IO API,插孔API等,都部署了Closeable界面,这意味着这些资源都能被关闭。有了Java 7,java.io.Closeable部署了AutoCloseable。因此,所有的操作都不会打乱已有代码。
NewResource代码如下:
public class NewResource implements AutoCloseable{
String closingMessage;
public NewResource(String closingMessage) {
this.closingMessage = closingMessage;
}
public void doSomeWork(String work) throws ExceptionA{
System.out.println(work);
throw new ExceptionA("Exception thrown while doing some work");
}
public void close() throws ExceptionB{
System.out.println(closingMessage);
throw new ExceptionB("Exception thrown while closing");
}
public void doSomeWork(NewResource res) throws ExceptionA{
res.doSomeWork("Wow res getting res to do work");
}
}
现在,让我们在使用try-with-resource的简单程序中尝试一下NewResource:
public class TryWithRes {
public static void main(String[] args) {
try(NewResource res = new NewResource("Res1 closing")){
res.doSomeWork("Listening to podcast");
} catch(Exception e){
System.out.println("Exception: "+
e.getMessage()+" Thrown by: "+e.getClass().getSimpleName());
}
}
}
输出结果是:
Listening to podcast
Res1 closing
Exception: Exception thrown while doing some work Thrown by: ExceptionA
上面代码中要注意一件事情,close抛出的异常被worker抛出的异常抑制住了。
因此,你要注意两个部署之间的差异,一个会使用try…catch…finally,另一个则使用try-with-resource。在上述举例中,只有一个描述过的资源被使用。程序员可以在try数据块中描述和使用多个资源,同样对这些try-with-resources 数据块进行嵌套。
除此以外,一些新方法和一个构造函数被添加到了java.lang.Throwable类中,它们与抑制异常有关系。例如,try数据块抛出的ExceptionA被finally抛出的ExceptionB所抑制,这是java 7之前中会出现的情况。
尽管如此,在Java 7中,抛出的异常会追踪它所抑制的异常。因此刚刚所说的举例可以用下面的语言重新描述。Close方法抛出的ExceptionB被添加到ExceptionA的异常抑制列表中,而ExceptionA由try数据块抛出。
我们用下面的举例来解释一下嵌套try-with-resources和被抑制的异常。
嵌套的try-with-resources
public class TryWithRes {
public static void main(String[] args) {
try(NewResource res = new NewResource("Res1 closing");
NewResource res2 = new NewResource("Res2 closing")){
try(NewResource nestedRes = new NewResource("Nestedres closing")){
nestedRes.doSomeWork(res2);
}
} catch(Exception e){
System.out.println("Exception: "+
e.getMessage()+" Thrown by: "+e.getClass().getSimpleName());
}
}
}
输出结果是:
Wow res getting res to do work
Nestedres closing
Res2 closing
Res1 closing
Exception: Exception thrown while doing some work Thrown by: ExceptionA
注意关闭资源的顺序。还要注意每个close()操作抛出的异常都被抑制了。
让我们看一看如何检索被抑制的异常:
被抑制的异常
public class TryWithRes {
public static void main(String[] args) {
try(NewResource res = new NewResource("Res1 closing");
NewResource res2 = new NewResource("Res2 closing")){
try(NewResource nestedRes = new NewResource("Nestedres closing")){
nestedRes.doSomeWork(res2);
}
} catch(Exception e){
System.out.println("Exception: "+
e.getMessage()+" Thrown by: "+e.getClass().getSimpleName());
if (e.getSuppressed() != null){
for (Throwable t : e.getSuppressed()){
System.out.println(t.getMessage()+
" Class: "+t.getClass().getSimpleName());
}
}
}
}
}
输出结果是:
Wow res getting res to do work
Nestedres closing
Res2 closing
Res1 closing
Exception: Exception thrown while doing some work Thrown by: ExceptionA
Exception thrown while closing Class: ExceptionB
Exception thrown while closing Class: ExceptionB
Exception thrown while closing Class: ExceptionB
getSuppressed()方法被用来检索被抛出异常抑制的其他异常。同样,Throwable类中添加了一个新的构造函数,而这个类可用来启用或禁用对异常的抑制。
原文链接: