2016-01-08 1 views
4

У меня есть базовый класс Base и дочерний класс Child, который его расширяет. Base инвентарь java.lang.AutoCloseable.Является ли метод close при идиоме try-with-resources не вызывается, если конструктор генерирует исключение?

Предположим, что конструктор для Child выбрасывает Foo.

Теперь рассмотрим

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

ли Base#close метод вызывается, если исключение? Это не на моей машине, но это что-то, что стандартизовало JLS?

+4

Если «конструктор для' Child' выбрасывает 'Foo', то экземпляр' Child' не существует в области вызова, поэтому 'close()' не может быть вызван. –

+0

Если объекта нет, на нем нельзя вызвать 'close'. –

ответ

9

Да, close не будет называться. Это указано в JLS section 14.20.3:

Ресурсы инициализируются в порядке слева направо. Если ресурс не инициализируется (то есть его выражение инициализатора генерирует исключение), то все ресурсы, инициализированные до сих пор оператором try-with-resources, закрыты. Если все ресурсы инициализируются успешно, блок try выполняется как обычно, а затем все ненулевые ресурсы оператора try-with-resources закрываются.

Ресурсы закрыты в обратном порядке от того, в котором они были инициализированы. Ресурс закрывается, только если он инициализирован значением, отличным от нуля,. Исключение из закрытия одного ресурса не препятствует закрытию других ресурсов. Такое исключение подавляется, если исключение было ранее выбрано инициализатором, блоком try или закрытием ресурса.

В этом случае исключение создается в конструкторе, поэтому ресурс не инициализируется значением, отличным от нуля. Следовательно, метод close не вызывается.

5

close не будет называться. Это не имело бы смысл называть, так как вы не имеете полностью сконструированный объект, чтобы закрыть, и в подобных звонках, вы не могли бы даже вступили в конструктор:

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

где makeBase является

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

Но базовый класс * полностью построен. Это то, с чем я сражаюсь. –

+4

@ P45Imminent: Java не имеет понятия базовых подобъектов. Нет полностью построенного объекта «Base»; объект не будет полностью построен до завершения конструктора 'Child'. – user2357112

+0

Спасибо за это. Выпущено, но не может грустно принять два ответа. –

Смежные вопросы