Поведение оператора return в catch и наконец - PullRequest
65 голосов
/ 18 апреля 2011

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

public class MyFinalTest {

    public int doMethod(){
        try{
            throw new Exception();
        }
        catch(Exception ex){
            return 5;
        }
        finally{
            return 10;
        }
    }

    public static void main(String[] args) {

        MyFinalTest testEx = new MyFinalTest();
        int rVal = testEx.doMethod();
        System.out.println("The return Val : "+rVal);
    }

}

Результатом является возвращаемое значение: 10.

Затмение показывает предупреждение: finally block does not complete normally.

Что происходит с оператором return в блоке catch?

Ответы [ 6 ]

73 голосов
/ 18 апреля 2011

Переопределяется значением в finally, потому что finally выполняется после всего остального.

Вот почему эмпирическое правило - никогда не возвращается из finally. Eclipse, например, показывает предупреждение для этого фрагмента: «наконец, блок не завершается нормально»

50 голосов
/ 18 апреля 2011

finally всегда выполняется (единственное исключение - System.exit()).Вы можете думать об этом поведении следующим образом:

  1. Выдается исключение
  2. Исключение перехватывается, и возвращаемое значение устанавливается в 5
  3. Наконец, блок выполняется и возвращаетзначение установлено в 10
  4. Функция возвращает
18 голосов
/ 18 апреля 2011

Это простой вопрос, если вы помните низкоуровневую компоновку виртуальной машины.

  1. Возвращаемое значение помещается в стек с помощью кода перехвата.
  2. После этогоНаконец, код выполняется и перезаписывает значение в стеке.
  3. Затем метод возвращает самое актуальное значение (10) для использования вызывающей стороной.

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

( забавный sidenote )

3 голосов
/ 20 мая 2017

enter image description here

Блок finally всегда выполняется до тех пор, пока оператор System.exit () не окажется первым в блоке finally.

Итак, в приведенном выше примере Exection генерируется оператором try и получает catch в блоке catch. Существует оператор return со значением 5 , поэтому в вызове стека значение 5 добавляется позже при выполнении блока finally, а последнее возвращаемое значение добавляется поверх стека при возврате значения, стек возвращает последний значение в соответствии со стековым поведением "LAST IN FIRST OUT" , поэтому возвращается значение 10.

3 голосов
/ 18 апреля 2011

Блок finally всегда выполняется (если была выполнена попытка сопоставления), поэтому, прежде чем метод вернет 5, как в блоке catch, он выполняет блок finally и возвращает 10.

0 голосов
/ 15 января 2014

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

Session session //  opened some session 
try 
{
 // some error 
}
catch { log.error }
finally 
{ session.logout();}

она не должна использоваться для возврата чего-либо.Вы можете использовать за пределами.

...