当前位置:  开发笔记 > 编程语言 > 正文

如果构造函数抛出异常,是否在try-with-resources习惯用法上调用close方法?

如何解决《如果构造函数抛出异常,是否在try-with-resources习惯用法上调用close方法?》经验,为你挑选了2个好方法。

我有一个基类Base和一个Child扩展它的子类.Base实施java.lang.AutoCloseable.

让我们假设构造函数Child抛出一个Foo.

现在考虑

try (Base c = new Child()){
    /*Some code*/
} catch (final Foo e){
    /*Some more code*/
}

Base#close如果抛出异常,是否调用该方法?它不在我的机器上,但这是JLS标准化的东西吗?



1> Tunaki..:

是的,close不会被叫.这在JLS 第14.20.3节中规定:

资源按从左到右的顺序初始化.如果资源无法初始化(即,其初始化程序表达式抛出异常),则会关闭try-with-resources语句到目前为止初始化的所有资源.如果所有资源都成功初始化,则try块将正常执行,然后关闭try-with-resources语句的所有非空资源.

资源以与初始化资源相反的顺序关闭.仅当资源初始化为非空值时才关闭资源.关闭一个资源的例外不会阻止关闭其他资源.如果先前由初始化程序,try块或资源关闭抛出异常,则会抑制此类异常.

在这种情况下,构造函数中会抛出异常,因此资源不会初始化为非null值.因此,close不调用该方法.



2> user2357112 ..:

close不会被叫.调用它是没有意义的,因为你没有一个完全构造的对象可以关闭,在类似的调用中,你甚至可能没有输入构造函数:

try (Base b = makeBase()) {
    ...
}

这里makeBase

Base makeBase() {
    throw new RuntimeException();
}


@ P45Imminent:Java没有任何基础子对象的概念.没有完全构造的"基础"对象; 在"Child"构造函数完成之前,该对象尚未完全构造.
推荐阅读
我我檬檬我我186
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有