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

System.exit() не рекомендуется. Это отключает JVM.

Другие вопросы по тегам