java继承和TryWithResources
假设有两个类实现AutoCloseable
接口,如下所示:
public class Closing1 implements AutoCloseable {
private boolean closed;
@Override
public void close() throws Exception {
if (closed) {
throw new Exception("Closed Already");
}
this.closed = true;
System.out.println("Closing1 closed");
}
public boolean isClosed() {
return closed;
}
}
及
public class Closing2 implements AutoCloseable {
private Closing1 cl1;
public Closing2(Closing1 cl1) {
this.cl1 = cl1;
}
@Override
public void close() throws Exception {
if(!cl1.isClosed()) {
throw new Exception("Closing1 not closed");
}
System.out.println("Closing2 closed");
}
}
我发现try-with-resources的所有变体都会导致异常!这里有没有我遗漏的东西,或者这只是TWR的设计方式
try(Closing1 c1 = new Closing1();Closing2 c2 = new Closing2(c1)){
System.out.println("Done");
} //Exception while auto closing C2
或
try(Closing1 c1 = new Closing1();Closing2 c2 = new Closing2(c1)){
System.out.println("Done");
c1.close();
} // exception while auto closing c1
# 1 楼答案
首先尝试使用资源,https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
正如第一个示例所示:
人们不一定会说出链中的每件事
除非您明确地需要c1来完成某些事情(而不是结束),否则在现实生活中,您的代码片段更像
而且您肯定不会在try块中调用
c1.close()
,因为根本没有c1记住这一点,因为包含的c1未关闭而从c2引发异常是完全错误的,实际上c2拥有Closing1对象,并且应该对其调用
close()
:但是,如果有人给c1命名,它将被关闭两次,这就是幂等性出现的地方,正如已经有人建议的:
正如前面提到的
BufferedReader
,这是它的close()
方法:如果它有
in
,它将被关闭并为null(在finally块中,即使发生异常也会发生),所有这些都在线程安全块中。(cb
只是一个字符数组,它也会变为null,从而稍微简化了垃圾收集器的使用寿命)。由于将finally块中的所有内容置零,因此对同一方法的任何额外调用都不会做任何事情(除了在锁上同步一段时间之外)# 2 楼答案
Try with resources将按与其声明相反的顺序关闭资源。这意味着将首先调用
c2.close()
,这将在编码异常时引发异常