Попробуйте, наконец, поток выполнения, когда return находится в try block

При попытке, наконец, используется комбинация, в попытке, если есть оператор return. Почему, наконец, блок выполняется первым?


class Palindrome
{
    public static void main(String args[]) 
    { 
        System.out.println(Palindrome.test()); 
    }

    public static int test()
    {
        try {  
                //return 0;  
                return 100;
        }  
        finally {  
            System.out.println("finally trumps return.");
        }
    }
}

В приведенном выше коде, пожалуйста, сообщите мне об исполнении. Я знаю, что окончательно будет выполняться по мандату после блока try. Но в блоке try, return staatement возьмет управление в основной класс. В этом случае, как будет закончен блок управления?

Ответ 1

Что вы подразумеваете под "первым"?

Выполняется finally перед выполнением этого метода. Когда еще это нужно? Это, в конце концов, часть метода.

Но если у вас

int x = 1;
try{
   return x;
} finally {
   x = x + 1;
}

тогда метод все равно вернет 1. Таким образом, оператор return выполняет выполнение перед блоком finally в некотором роде (для определения возвращаемого значения).

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

Но в блоке try блок return возвращает элемент управления в основной класс. В этом случае, как будет закончен блок управления?

Как? Ну, именно так работает язык (и время выполнения).

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

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

Ответ 2

Потому что это определение блока finally. Это всегда происходит, независимо от того, как выйдет блок. Наконец, существуют блоки для операций, которые ДОЛЖНЫ всегда выполняться, например, закрывать открытые потоки и очищать соединения сокетов. Независимо от того, как выйдет блок, код в блоке finally всегда должен выполняться. Если вы хотите пропустить код, если блок try успешно завершен, то он принадлежит блоку catch() с соответствующим типом исключения.

Ответ 3

Из https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html

Блок finally всегда выполняется, когда блок try завершается. Эта гарантирует, что блок finally будет выполнен, даже если неожиданное исключение. Но, наконец, полезно не только для исключения обработка - это позволяет программисту избежать кода очистки случайно обходится возвратом, продолжается или прерывается. Помещение очистки код в блоке finally всегда является хорошей практикой, даже если нет исключения ожидаются

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

Таким образом, ответ на ваш вопрос по дизайну. Java предназначен для работы таким образом.

Ответ 4

Из https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html

Наконец, блок должен всегда проектироваться:

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

Если вы вернетесь в блок try и код в finally, блок не будет выполнен, это не "всегда выполняется".

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

public static void main(String[] args) throws IOException {
    InputStream is;
    try {
        is = getInpustStreamFromNetwork();
        int i = 1 / 0;// 1. Intruduces exceptions
        return;// 2. returns before clean up resources
    } finally {
        is.close();// clean up resources is important, so it is a good practice to put it into finally block even though there is no exceptions to catch.
        System.out.println("no matter #1 or #2 ,this will be executed\n,");
    }
}