Использование Java, наконец, достаточно, чтобы прочитать эту статью

Java

Эта статья переведена с разрешения команды baeldung.

Английский оригинал:ууууууу. поместите класс arlingtonterrier.com/java-final…

1 Обзор

В этом уроке мы изучим использование ключевого слова finally в Java. Мы увидим, как использовать его с блоками try/catch при обработке ошибок. Хотя цель finally — гарантировать выполнение кода, мы также обсудим особый случай, когда JVM не выполняет код finally.

Мы также обсудим некоторые распространенные ловушки, когда блоки finally могут привести к неожиданным результатам.

2. Что в итоге

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

Обычно блок finally выполняется независимо от того, выброшено или перехвачено исключение.

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

try {
    System.out.println("The count is " + Integer.parseInt(count));
} catch (NumberFormatException e) {
    System.out.println("No count");
} finally {
    System.out.println("In finally");
}

В этом примере JVM выполняет блок finally и печатает «In finally» независимо от значения параметра.

2.2 Наконец-то без блока catch

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

результат

Inside try Insidefinally

2.3 Сценарий использования finally

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

3. Время выполнения наконец

3.1 Без исключений

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

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

Inside try Inside finally

3.2 Есть исключение, но нет обработчика

Блок finally все равно будет выполняться, даже если исключение не перехвачено.

try {
    System.out.println("Inside try");
    throw new Exception();
} finally {
    System.out.println("Inside finally");
}

Даже если возникнет необработанное исключение, JVM все равно выполнит код в блоке finally.

Inside try Inside finally Exception in thread "main" java.lang.Exception

3.3 С обработчиками исключений

В блоке кода try возникает исключение, которое перехватывается catch и, наконец, все равно будет выполнено.

try {
    System.out.println("Inside try");
    throw new Exception();
} catch (Exception e) {
    System.out.println("Inside catch");
} finally {
    System.out.println("Inside finally");
}

Inside try Inside catch Inside finally

3.4 Возвращаемое значение в блоке try

Даже если вы вернетесь из блока try, вы не сможете предотвратить выполнение блока finally.

try {
    System.out.println("Inside try");
    return "from try";
} finally {
    System.out.println("Inside finally");
}

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

Inside try Inside finally

3.5 Возврат в блоке catch

Добавьте оператор return в блок catch, и код finally все равно будет выполняться.

try {
    System.out.println("Inside try");
    throw new Exception();
} catch (Exception e) {
    System.out.println("Inside catch");
    return "from catch";
} finally {
    System.out.println("Inside finally");
}

результат

Inside try Inside catch Inside finally

4 Когда ваще не исполнится

Хотя блок finally обычно пишется так, что код должен выполняться, существуют особые случаи, когда JVM не выполняет блок finally.

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

4.1 Вызов функции System.exit

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

результат

Inside try

4.2 Вызов функции остановки

try {
    System.out.println("Inside try");
    Runtime.getRuntime().halt(1);
} finally {
    System.out.println("Inside finally");
}

Inside try

4.3 Демонические потоки

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

Runnable runnable = () -> {
    try {
        System.out.println("Inside try");
    } finally {
        try {
            Thread.sleep(1000);
            System.out.println("Inside finally");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};
Thread regular = new Thread(runnable);
Thread daemon = new Thread(runnable);
daemon.setDaemon(true);
regular.start();
Thread.sleep(300);
daemon.start();

вывод

Inside try Inside try Inside finally

4.4 Бесконечный цикл в блоке try

try {
    System.out.println("Inside try");
    while (true) {
    }
} finally {
    System.out.println("Inside finally");
}

Блок Try бесконечно повторяется без исключения и, наконец, никогда не выполняется.

5. Распространенные ошибки

Мы сталкиваемся с множеством ошибок при использовании ключевого слова finally.

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

5.1 Игнорирование исключений

Блок finally содержит оператор return и не обрабатывает неперехваченные исключения.

try {
    System.out.println("Inside try");
    throw new RuntimeException();
} finally {
    System.out.println("Inside finally");
    return "from finally";
}

В этот момент исключение RuntimeException в блоке try игнорируется, и функция возвращает строку «from finally».

5.2 Переопределение других операторов возврата

Если в блоке finally есть оператор return, блоки try и catch игнорируются, если есть оператор return.

try {
    System.out.println("Inside try");
    return "from try";
} finally {
    System.out.println("Inside finally");
    return "from finally";
}

Этот код всегда возвращает "from finally".

5.3 Изменение поведения броска или возврата

Если в блоке finally генерируется исключение, операторы throw или return в try и catch будут проигнорированы.

try {
    System.out.println("Inside try");
    return "from try";
} finally {
    throw new RuntimeException();
}

Этот код никогда не возвращает значение и всегда генерирует исключение RuntimeException.

6. Заключение

В этой статье мы обсудили использование ключевого слова finally в Java. Затем обсуждается случай выполнения и невыполнения блока finally.

Наконец, приведены подводные камни общего использования finally в разработке.

Если вам нужен код этой статьи, вы можете перейти на GitHubПоддержка проектаСкачать в.


7. Вопросы для размышления

Переводчик добавляет:В сочетании с примером в части 4 вы можете подумать, есть ли другой способ сделать наконец не выполненным?Вы можете оставить комментарий ниже.


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