本文讲解了try-with-resources语句的使用。这是一个表明了一个以上资源的尝试性语句。一个资源就如同程序结束后必须关闭的对象一样。
Try-with-resources语句确保了每个资源都在语句使用后被关闭。任何部署java.lang AutoCloseable或java.io.Closeable 界面的对象都可当做资源使用。
在try-with-resources之前,处理SQL语句或ResultSet或Connection对象或其他IO对象时,操作者不得不明确用关闭命令关闭资源。所以可能要写出如下代码:
try{
//Create a resource- R
} catch(SomeException e){
//Handle the exception
} finally{
//if resource R is not null then
try{
//close the resource
}
catch(SomeOtherException ex){
}
}
我们不得不用明确的关闭命令来关闭资源,因此要添加更多代码。在某些案例中个,程序员可能关闭资源。因此必须克服这种情况和其他Java 7中的try-with-resources事项。
让我们看一下如何在Java 7之前的版本中使用try…catch语句。让我们创建两个自定义异常-Exception A和Exception B。二者将在举例中出现。
public class ExceptionA extends Exception{
public ExceptionA(String message){
super(message);
}
}
public class ExceptionB extends Exception{
public ExceptionB(String message){
super(message);
}
}
再创建一些资源,称作OldResource,它包含两个方法-doSomeWork():和close():。
注意,这样就描述了通用资源-doSomeWork的使用,然后再将其关闭。现在每个操作doSomeWork和close,都抛出了一个异常。
public class OldResource{
public void doSomeWork(String work) throws ExceptionA{
System.out.println(\"Doing: \"+work);
throw new ExceptionA(\"Exception occured while doing work\");
}
public void close() throws ExceptionB{
System.out.println(\"Closing the resource\");
throw new ExceptionB(\"Exception occured while closing\");
}
}
让我们在一个简单程序中使用这个资源:
public class OldTry {
public static void main(String[] args) {
OldResource res = null;
try {
res = new OldResource();
res.doSomeWork(\"Writing an article\");
} catch (Exception e) {
System.out.println(\"Exception Message: \"+
e.getMessage()+\" Exception Type: \"+e.getClass().getName());
} finally{
try {
res.close();
} catch (Exception e) {
System.out.println(\"Exception Message: \"+
e.getMessage()+\" Exception Type: \"+e.getClass().getName());
}
}
}
}
输出结果是:
Doing: Writing an article
Exception Message: Exception occured while doing work Exception Type: javaapplication4.ExceptionA
Closing the resource
Exception Message: Exception occured while closing Exception Type: javaapplication4.ExceptionB
该程序直截了当:创建一个新资源,使用这个资源,然后将其关闭。程序员可以看看多出来的几行代码。
现在让我们用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类中添加了一个新的构造函数,而这个类可用来启用或禁用对异常的抑制。
原文链接:
http://www.javacodegeeks.com/2011/07/java-7-try-with-resources-explained.html
本文链接: http://newresource.immuno-online.com/view-717724.html