Какова суть наконец блока в Java?

Я думаю на следующих примерах; но не мог выяснить, каков важность наконец блок. Можно ли сказать мне различие выполнения этих двух примеров кода? Также реальный пример может быть полезным.

Демонстрационный 1:

    try{
       // some code 1
    }catch(Exception ex){
       // print exception   
    }finally{
       // some code 2            
    }

Демонстрационные 2:

    try{
      // some code 1
    }catch(Exception ex){
      // print exception   
    }
    // some code 2
8
задан Péter Török 30 June 2010 в 08:59
поделиться

7 ответов

В двух представленных вами фрагментах есть большая разница, например когда сам блок catch генерирует исключение, блок finally по-прежнему будет выполняться в соответствии с его семантикой.

Это следующий фрагмент печатает «Наконец-то!» , но не «Что насчет меня ???» :

    try {
        throw null;     // throws NullPointerException!
    } catch (Exception e) {
        int oops = 1/0; // throws ArithmeticException!
    } finally {
        System.out.println("Finally!"); // still gets executed!
    }
    System.out.println("What about me???"); // doesn't get executed!

В общем, finally блока try практически всегда выполняется . Нет такой гарантии для любого кода, следующего за блоком try .


Но что, если мой блок catch - это всего лишь простой оператор print ?

По-прежнему нет гарантии , что он не выбросит что-то. Что-то все еще могло пойти не так, например, конструкция для подробного сообщения об исключении.

Даже если вы сделаете все возможное, чтобы гарантировать, что код catch является «безопасным», а код, следующий за оператором try , всегда будет выполняться, тогда возникает вопрос: «Почему? ". Зачем избегать finally , а затем так стараться воспроизвести его семантику?

finally семантика гарантирована, не требуя бремени доказательства ни от автора, ни от читателя кода. Именно из-за этого идиоматично использовать блок finally для установки обязательного кода «очистки». Использование finally гарантирует правильность и улучшает как возможность записи, так и читаемость.

17
ответ дан 5 December 2019 в 05:55
поделиться

это полезно, когда мы хотим освободить ресурсы, которые мы использовали в блоке try. Так что единственное место, где можно их выполнить, ни в коем случае не пропуская, - это finally block. Поскольку, если возникает исключение, java не выполняет код сразу после этого. он сразу переходит к блоку захвата.

1
ответ дан 5 December 2019 в 05:55
поделиться

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

Обратите внимание, что обычно блоки catch перехватывают более конкретные типы исключений - часто только проверенные исключения - поэтому в большинстве случаев разница между двумя приведенными выше примерами кода очень очевидна.

Обновление: вы можете сказать, что ваш блок catch никогда не может генерировать исключение, поэтому finally не требуется.Однако обратите внимание на две вещи:

  • это только текущее состояние кода, и оно может измениться в будущем - можете ли вы гарантировать, что будущий программист, который добавит некоторый потенциально генерирующий исключение код в блок catch , запомнит ли помещать код очистки после него в блок finally ?
  • try-catch-finally - это идиома программирования что помогает людям, читающим код, понять, что происходит. Если вы не используете общепринятую идиому, вы рискуете непонимание, а значит, и ошибки в долгосрочной перспективе.
8
ответ дан 5 December 2019 в 05:55
поделиться

В реальной жизни блок finally используется для закрытия открытых ресурсов даже в случае возникновения исключения. Например, когда вы читаете (или записываете) файл, когда вы обращаетесь к базе данных и т. Д.

public void readFile(String fileName) {
    FileReader fr;
    BufferedFileReader bfr;

    try {
        fr = new FileReader(fileName);
        bfr = new BufferedFileReader(fr);
        // ...
    } catch (IOException ioe) {
        // ...
    } finally {
        // TO ENSURE THAT THE READERS ARE CLOSED IN ALL CASES
        if (bfr != null) { 
            try {
                bfr.close();
            } catch (IOException ignoredIOE) {}
        }
        if (fr != null) { 
            try {
                fr.close();
            } catch (IOException ignoredIOE) {}
        }
    }
}
0
ответ дан 5 December 2019 в 05:55
поделиться

Вы используете блок finally для очистки и запуска любого кода, который должен выполняться независимо от того, было создано (и перехвачено) исключение или нет. Сюда входит код из блока catch .

2
ответ дан 5 December 2019 в 05:55
поделиться

В случае, если операторы в блоке try вызывают непроверенные исключения, блок finally выполняется, позволяя программисту предпринять соответствующие действия.

0
ответ дан 5 December 2019 в 05:55
поделиться

Обратите внимание, что вы можете даже попробовать-finally без уловки:

try{
   // some code 
}finally{
   // cleanup code
}

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

0
ответ дан 5 December 2019 в 05:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: