С каким кодом завершится программа при выброшенном исключении в Java
Что проверяют
Понимаете ли вы, что происходит после того, как исключение никто не поймал: кто его печатает, с каким статусом завершается процесс и что успевает выполниться. Вопрос любят потому, что от этого зависит поведение сервиса в контейнере и в скриптах: оркестратор смотрит именно на код возврата.
Как отвечать
Коротко: нормальное завершение даёт ноль, необработанное исключение, вылетевшее из main, даёт единицу. Стек печатает обработчик по умолчанию в поток ошибок, само исключение на код возврата не влияет, своего номера у него нет.
Дальше разверните детали:
- явный
System.exit(code)задаёт любой код, при этом блокиfinallyуже не выполняются; Runtime.haltзавершает процесс жёстко, минуя хуки завершения, аSystem.exitих запускает;- необработанное исключение в отдельном потоке убивает только этот поток, процесс спокойно завершится нулём, если остальные потоки отработают штатно;
- ошибки вроде нехватки памяти идут тем же путём, что и исключения, если не задан флаг принудительного завершения виртуальной машины;
- процесс, убитый сигналом, оболочка покажет кодом больше ста двадцати восьми, но это уже про операционную систему, а не про Java.
Полезно добавить, что общий обработчик ставится через Thread.setDefaultUncaughtExceptionHandler, и именно туда вешают логирование падений фоновых задач.
Где спотыкаются
Считают, что код возврата зависит от типа исключения. Такой связи нет: любое неперехваченное исключение из главного потока даёт одну и ту же единицу, различать причины нужно по логу.
Уверены, что finally выполняется всегда. При System.exit внутри try блок пропускается, а return внутри самого finally вдобавок проглатывает исключение, и падение исчезает бесследно.
Забывают про фоновые потоки. Пул выполняет задачу, она падает, процесс живёт дальше с нулевым статусом, а снаружи всё выглядит здоровым. Ещё тише с submit: исключение остаётся внутри Future и без вызова get не всплывает нигде.