Метод System.exit() в Java
Метод System.exit() используется в языке Java для завершения программы: он останавливает виртуальную машину Java (JVM) вместе со всеми её потоками. Метод принимает на вход одно значение типа int — код завершения (exit code, status). Обычно это 0, что означает, что программа завершилась без ошибок. Любое другое значение сообщает операционной системе, что программа завершилась с ошибкой.
Как работает System.exit()
Вызов System.exit(status) — это сокращение для Runtime.getRuntime().exit(status). Метод запускает процедуру завершения JVM:
- выполняются все зарегистрированные shutdown hooks (обработчики завершения);
- после этого виртуальная машина останавливается и возвращает операционной системе переданный код завершения.
Важно понимать: System.exit() никогда не возвращает управление в вызвавший его код. Все операторы, стоящие после вызова, выполнены не будут — независимо от того, в каком методе и на какой глубине вызовов произошёл выход.
Коды завершения: 0, 1 и другие
Код завершения (exit code) — это число, которое процесс возвращает операционной системе. По соглашению, принятому в большинстве ОС:
| Код завершения | Значение | Когда используют |
|---|---|---|
0 | Успешное завершение | Программа отработала штатно, без ошибок |
1 | Общая ошибка | Самый распространённый код аварийного завершения |
| Другие ненулевые | Конкретный тип ошибки | Приложение само определяет смысл кодов (например, 2 — неверные аргументы) |
Код завершения важен при запуске Java-программ из скриптов и систем сборки: по нему shell-скрипт, CI-сервер или планировщик задач понимают, успешно ли отработала программа. Проверить код последнего процесса можно так:
# Linux / macOS
java SysExitExample
echo $?
# Windows (cmd)
java SysExitExample
echo %ERRORLEVEL% Обратите внимание: в Unix-подобных системах операционная система хранит только младший байт кода, поэтому осмысленный диапазон значений — от 0 до 255.
Пример использования System.exit()
Рассмотрим пример:
public class SysExitExample {
public static void main(String[] args) {
System.out.println("До возврата.");
method(true);
System.out.println("Этот оператор выполняться не будет.");
}
public static void method(boolean flag) {
if (flag) {
System.exit(0);
}
System.out.println("Этот оператор метода выполняться не будет.");
}
} Результат выполнения программы:
До возврата. Программа напечатала только первую строку: вызов System.exit(0) внутри метода method() остановил JVM, поэтому не выполнился ни оставшийся код самого метода, ни код в main() после вызова.
На чём часто ошибаются
Если System.exit() вызван внутри блока try, то блок finally не выполнится: JVM останавливается сразу, не разматывая стек вызовов. Это популярный вопрос на собеседованиях — ресурсы, которые вы рассчитывали закрыть в finally, останутся незакрытыми.
System.exit() и return: в чём разница
Начинающие иногда путают System.exit() с оператором return, хотя работают они по-разному:
returnзавершает только текущий метод и возвращает управление вызвавшему коду. Программа продолжает работать. Подробнее — в уроке об операторах перехода.System.exit()завершает всю программу: останавливаются все потоки, JVM выгружается из памяти.
Отдельный случай — return в методе main(). Он завершает main(), но JVM продолжит работу, если в программе остались живые потоки, не являющиеся демонами. System.exit() остановит JVM в любом случае.
Когда System.exit() лучше не использовать
В простых консольных программах System.exit() уместен — например, чтобы вернуть ненулевой код при неверных аргументах командной строки. Но есть ситуации, где его вызов считается плохой практикой:
- Веб-приложения и серверный код. Вызов
System.exit()остановит весь сервер приложений вместе с другими развёрнутыми приложениями. - Библиотеки. Библиотечный код не должен решать за приложение, когда завершаться, — вместо этого выбрасывайте исключение.
- Юнит-тесты. Вызов
System.exit()в тестируемом коде завершит процесс тестового раннера.
В обычной логике программы для выхода из метода используйте return, а об ошибках сообщайте исключениями.
Часто задаваемые вопросы
Что означает System.exit(0) в Java?
Вызов System.exit(0) немедленно завершает программу с кодом 0 — по соглашению это признак успешного завершения без ошибок. Код возвращается операционной системе, и его могут проверить скрипты, запустившие программу.
Чем System.exit(0) отличается от System.exit(1)?
Для JVM разницы нет — программа завершится в обоих случаях. Разница в смысле кода для операционной системы: 0 означает успех, 1 (и любое другое ненулевое значение) — завершение с ошибкой. По коду внешние скрипты и CI-системы определяют результат работы программы.
Выполнится ли блок finally после вызова System.exit()?
Нет. System.exit() останавливает JVM без «разматывания» стека вызовов, поэтому блоки finally и код после try-catch не выполняются. Выполнятся только зарегистрированные shutdown hooks.
Чем System.exit() отличается от Runtime.halt()?
System.exit() запускает штатную процедуру завершения: выполняются shutdown hooks, затем JVM останавливается. Runtime.getRuntime().halt() останавливает JVM мгновенно, не выполняя shutdown hooks. Halt применяют в крайних случаях, например если процедура завершения зависла.
Видео объяснение
Предпочитаете видеоформат? Посмотрите этот урок с примерами и объяснениями.
Комментарии