#java #exception #stack-trace
Вопрос:
Вот мой простой тестовый код:
class Scratch {
public static void main(String[] args) {
try {
System.out.println("Line 1");
throw new RuntimeException();
} catch (RuntimeException e) {
e.printStackTrace();
} finally {
System.out.println("Line 2");
}
}
}
После пробежки я получу это:
Line 1
Line 2
java.lang.RuntimeException
at Scratch.main(scratch_4.java:5)
Process finished with exit code 0
Я думал, что «наконец-то» код должен быть наконец-то выполнен, но это не так.
В чем причина?
Комментарии:
1. Я думаю, что, наконец, просто определено, что он должен выполняться до ввода кода
catch
. Я должен был бы посмотреть это в спецификации языка, хотя, чтобы быть уверенным.2. @markspace: Нет, он определенно выполняется после блока catch.
3. Я принимаю поправку! Я оставлю свой комментарий, хотя, поскольку я думаю, что это иллюстрирует возможное недоразумение.
4. @markspace Я собирался сказать, что ключевое
finally
слово должно дать понять, что это последнее, что должно произойти; но затем я заметил, что в руководстве по Oracle говорится : «Блок finally всегда выполняется при выходе блока try»., что является довольно вводящим в заблуждение утверждением. Как говорит ДжоНскит: он определенно выполняется после перехвата, если при попытке было создано соответствующее исключение.
Ответ №1:
По умолчанию printStackTrace
печатается на System.err
, в то время как вы пишете на System.out
. Таким образом, вы пишете в два разных потока, и в вашем конкретном случае похоже, что задействованная буферизация изменила порядок вывода из фактического порядка выполнения.
Если вы либо пишете в один поток (например, используя System.err.println
или вызывая e.printStackTrace(System.out)
), либо измените свой catch
блок, чтобы просто писать System.out
, как это делают другие ваши строки, вы увидите порядок try => catch =>> наконец.