System.exit(num) или выбросить RuntimeException из main?
У меня есть однопоточное приложение, которое должно установить уровень ошибки DOS на ненулевое значение, если есть проблема. Лучше бросить RuntimeException или использовать System.exit(ненулевой)? Мне не нужна трассировка стека, и я не ожидаю, что это приложение будет расширено / повторно использовано. Каковы различия между этими двумя вариантами?
6 ответов
Не бросайте исключения, если у вас действительно нет исключительного состояния. System.exit(int)
именно по этой причине. Используй это.
РЕДАКТИРОВАТЬ: Я думаю, что я мог неправильно понять ваш вопрос. Я думал, что вы спрашиваете, когда вы хотите выйти из JVM в обычном режиме, но сигнализируете, что что-то идет не так, лучше ли бросить исключение или использовать System.exit
,
Однако, если возникает проблема, которая уже указана в исключении Java, можно просто оставить это исключение необработанным. Вам не нужно ловить исключение и звонить System.exit
,
Если у вас есть выбор: бросить исключение или позвонить System.exit
Подумайте, не является ли условие ошибки чем-то, что могло бы быть обработано некоторым Java-кодом, вызывающим ваш метод. Если ошибка происходит непосредственно в main
метод, то, вероятно, никогда не будет вызывающего для обработки исключения, поэтому вы, вероятно, должны вызвать System.exit
, В противном случае, обычно лучше создать исключение, но не RuntimeException
Вы, вероятно, должны использовать тип исключения, который надлежащим образом представляет ошибку, с которой вы столкнулись. Напишите свой собственный подкласс RuntimeException
если необходимо.
Обычно в этой ситуации я бы обрабатывал все исключения в моем основном методе, возможно, вызывая System.exit
, Это дает вам гибкость в отношении того, где / следует ли / как обрабатывать исключительные условия, в то же время удовлетворяя вашу потребность завершать работу с кодом ошибки. В частности, он дает вам контроль над кодом возврата и любым другим выводом, который вы можете сгенерировать для пользователя (сообщение об ошибке, трассировка стека и т. Д.). Если вы бросите исключение в main (или исключите исключение), вы потеряете этот контроль.
Подводя итог, позвоните System.exit
только в вашем обработчике исключений верхнего уровня:
static public void main() {
try {
runMyApp();
} catch (Exception e) {
System.exit(1);
}
}
Созданное исключение распечатает трассировку стека, и если вам это не нужно, вы должны использовать System.exit.
После выхода вы можете проинформировать пользователя с помощью Sytem.out (я предполагаю, что приложение работает только в среде commanline).
Вы должны рассмотреть возможность перехвата всех ошибок и регистрации ошибок в отдельном журнале, это гарантирует, что трассировка стека не будет потеряна навсегда при закрытии терминала. Посмотрите на log4j для этой цели, он действительно прост в использовании.
Само приложение должно использовать System.exit. Это его интерфейс с вызывающей средой (скрипт). Любой внутренний компонент, конечно, должен использовать исключение. Когда вы соедините это вместе, это может быть оба из них:
Application.main(...) {
parse(args);
check(...);
try {
MyObject o = ...;
o.doMyStuff();
} catch (Exception e) {
System.err.println("Oops, something went wrong!"); // by example, or use a logging framework! // anyway in a shell app System.in/out/err IS my interface with the outworld
System.exit(ERROR_CODE);
}
System.out.println("Worked!");
}
Это зависит от того, сколько информации вы хотите передать скрипту, запускающему вашу программу. Это может быть очень важно, если сценарий предназначен для выполнения цепочки действий. https://shapeshed.com/unix-exit-codes/
Пример: я разработал программу на Java, которая вызывает внешний API, загружает ответ и сохраняет его в файл. Возможные исходы:
- 0 = ОК
- 5 = HTTP временно недоступен
- 6 = Невозможно записать файл на диск
Теперь мой сценарий знает, что пошло не так, и может предпринимать разные действия в зависимости от результата.
- Если response = 0, продолжить следующий шаг в скрипте
- Если ответ = 5, повторить попытку (с задержкой)
- Если response = 6, остановить скрипт
Итог: как и любой хороший API, четко определите параметры ввода и вывода и используйтеSystem.exit
.
System.exit(num) не является хорошим вариантом, так как закрывает JVM, плюс даже он не запускает блок finally, если у вас есть после блока catch.
Бросок RuntimeException также может быть не лучшим вариантом, может подкласс, как упоминалось ранее, который является конкретным исключением приложения, может быть лучшим вариантом, на мой взгляд. -Manish