Будет ли достигнут блок finally, если в блоке try есть блок Where (true)?

Вот код меня озадачил:

public Integer getInteger(BlockingQueue<Integer> queue) {
    boolean interrupted = false;
    try {
        while (true) {
            try {
                return queue.take();
            } catch (InterruptedException e) {
                interrupted = true;
                // fall through and retry
            }
        }
    } finally {
        if (interrupted)
            Thread.currentThread().interrupt();
    }
}

Кажется, что блок try не остановится из-за блока While(true), но мне сказали, что блок finally всегда будет выполняться после завершения блока try. Итак, когда будет выполняться блок finally?


person user2916610    schedule 22.10.2015    source источник
comment
Я не думаю, что вы достигнете блока finally, если у вас действительно есть бесконечный цикл в блоке try.   -  person Tim Biegeleisen    schedule 22.10.2015


Ответы (2)


когда есть другое исключение, которое не является производным от InterruptedException

person Valery Gavrilov    schedule 22.10.2015
comment
Ваш ответ правильный, но мне кажется, что ему следует переработать свою логику, чтобы программа не зависела от исключения. - person Tim Biegeleisen; 22.10.2015
comment
Или когда нет исключения queue.take(), вызывающего возврат. - person Patricia Shanahan; 22.10.2015

Блок finally будет выполнен после завершения блока try, что в вашем случае может быть по двум причинам:

  • queue.take() завершается нормально, что означает, что он возвращает значение, которое приводит к нормальному завершению оператора return и возврату из метода со значением из take().
  • queue.take() завершается резко, выбрасывая Exception (или Error), кроме InterruptedException.

Сокращенная цитата из спецификации языка Java Выполнение try-finally и try-catch-finally:

  • Если выполнение блока try завершается нормально, то выполняется блок finally [...]

  • Если выполнение блока try внезапно завершается из-за выбрасывания значения V, то есть выбор:

    • Если тип времени выполнения V совместим по присваиванию с перехватываемым классом исключения любого предложения catch [...], тогда есть выбор:

      • Если блок catch завершается нормально, то выполняется блок finally [...]

      • Если блок catch завершается внезапно по причине R, то выполняется блок finally [...]

    • Если тип времени выполнения V не совместим по присваиванию с перехватываемым классом исключения любого предложения catch оператора try, то выполняется блок finally [...]

  • Если выполнение блока try завершается внезапно по любой другой причине R, то выполняется блок finally [...]

Все пути ведут к выполнению блока finally.

Короче говоря, блок finally всегда выполняется, когда завершается блок try по любой причине. Единственный способ избежать этого — ненормальное завершение работы JVM (например, уничтожение JVM, сбой JVM, сбой ОС или отключение питания).

person Andreas    schedule 22.10.2015