2015-10-12 2 views
0

Итак, мне назначили научить блок обработке исключений, и я столкнулся с вопросом, на который у меня нет ответа. Какие действительные (например, не приводят к компилятору или времени выполнения) команды в Java не будут выполнять окончательный блок?Допустимые команды, которые сохраняют блок finally от выполнения на Java

Оператор return не будет делать этого, но заявление System.exit(0) будет. Мое понимание состоит в том, что блок finally будет выполняться независимо от того, что. Какие (действительные) операторы будут препятствовать тому, чтобы блок finally сделал это, и почему?

+0

Целью 'finally' является выполнить что-то независимо от того, что (в терминах сценария try-catch). Таким образом, выборочное обход «наконец» использует механизм для достижения чего-то, что не предназначено для этого. Я предполагаю, что есть некоторая проблема в логическом потоке/дизайне. Есть ли у вас какой-то прецедент, когда это необходимо или это общий вопрос? Используя 'exit', тогда звучит правильный ответ, если продолжение программы не ожидается. –

+0

'Machine.emergencyPowerOff()' – ZhongYu

ответ

2

Цитирование Docs:

Если виртуальная машина выходит в то время как попытка поймать или код выполняется, то, наконец, блок не может выполнить. Аналогично, если поток , выполняющий код try или catch, прерван или убит, блок finally может не выполняться, даже если приложение в целом продолжается.

Что касается вашего примера о System.exit(), цитируя Docs снова

Завершает в настоящее время работает на Java Virtual Machine. Аргумент служит в качестве кода состояния; по условному выражению, ненулевой код состояния указывает на ненормальное завершение.

Это означает, что finally не будет выполнен.

Простой пример:

try { 
    System.out.println("try"); 
    System.exit(0); 
} finally { 
    System.out.println("finally"); 
} 

Приведенный выше пример будет печатать только try, но не finally

1

Цитирую Oracle's tutorials:

Примечание: Если виртуальная машина выходит в то время как попытка или код catch выполняется, тогда блок finally может не выполняться. Аналогично, если поток, выполняющий код try или catch, прерывается или убивается, блок finally может не выполняться, даже если приложение в целом продолжается.

System.exit просто совсем JVM, тем самым предотвращая finally блок от бега, как будет убивать поток, содержащий этот блок из другого потока. Другой краевой регистр имеет бесконечный цикл в блоке try, который просто предотвратит его завершение, поэтому цикл finally никогда не будет достигнут.

1

Я вижу три случая никогда не достигнет finally блока (или какие-либо дополнительные инструкции в кадре стека):

  1. Внезапная смерть нити (в том числе JVM выхода)
  2. операции стека кадров
  3. Infinite петля; независимо от его активного (while (true)) или пассивного (эквайринг блокировки, ожидая уведомления и т.д.)

Только машинный коду (в том числе собственных механизмов виртуальной машины Java) должен убить нить или играть с кадрами стека. Также возможны фатальные системные ошибки.

Однако реализации JVM вольны предложить такую ​​(нежелательную?) Функцию по его конкретному API (т.е. sun.misc.Unsafe) или через уродливую реализацию Java SE API (т.е. Thread.destroy)

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