try-with-resource写法对构造器抛异常的处理
如果我们在类的构造器里抛出异常,try-with-resource写法是没法自动调close的。逻辑上很好理解,你对象都没成功创建,我为啥要调close啊。
从反编译的代码里也可以看出端倪:
MyParser parser = new MyParser(path);Throwable var3 = null;try {// do sth here...} catch (Throwable var13) {var3 = var13;throw var13;} finally {if (parser != null) {if (var3 != null) {try {parser.close();} catch (Throwable var12) {var3.addSuppressed(var12);}} else {parser.close();}}}
我们会看到,try-with-resource依然会翻译为try-finally,在finally里面,是要明确判断构造对象parser是否为null,不为null,才会调用其close方法的。一旦构造器抛异常,parser肯定是null,所以其close不会调用。
所以,如果构造器里涉及某些资源创建(例如文件),同时可能抛异常,就要在构造器里做好异常下的资源清理,而不能指望close方法自动完成。
这样的处理逻辑跟C++也是一样的。