Я пишу программу на Java, которая читает файл слов. Программа в значительной степени зависит от этого файла, поэтому я действительно хочу, чтобы программа завершилась, если по какой-либо причине при чтении файла возникнет исключительная ситуация IOException.
Как лучше всего завершить программу? Я думаю, что я вынужден заключить чтение файла в блок try / catch, поэтому должен ли я добавить System.exit (0)
в свой catch? Например, следует ли мне сделать что-то вроде следующего?
try {
BufferedReader br = new BufferedReader(new FileReader("myfile.txt"));
String line;
while ((line = br.readLine()) != null) {
// process...
}
} catch(IOException e) {
System.out.println("Error: " + e);
System.exit(0); // ???
}
Это нормально. Однако 0
в качестве кода выхода означает, что программа завершилась, как и ожидалось. Вы захотите использовать другой номер;)
@gratur спрашивает в комментарии к ответу @ skaffman.
Итак, если я правильно понимаю, я позволил исключению всплыть, удалив блок try / catch и добавив к этому методу «throws IOException» (и методы, которые вызывают этот метод и т. Д.)? Я чувствую себя немного непристойно, потому что теперь мне нужно добавлять кучу «бросков IOException» - моя заблуждение ошибочно?
Я думаю, что это зависит. Если исключение должно содержать только небольшое количество уровней, и для методов имеет смысл распространять IOException
, то это то, что вы должны сделать. Нет ничего особенно "непристойного" в том, чтобы разрешить распространение исключения.
С другой стороны, если IOException
приходится распространяться по многим уровням и нет никаких шансов , что он может быть обработан конкретно за пределами определенной точки, вы можете захотеть:
ApplicationErrorException
, который является подклассом RuntimeException
, IOException
рядом с его источником и бросает ApplicationErrorException
на его место ... с cause
set конечно, и ApplicationErrorException
в вашем методе main
. В точке main
, где вы перехватываете ApplicationErrorException
, вы можете вызвать System.exit()
с ненулевым кодом состояния и при необходимости распечатать или записать трассировку стека. (На самом деле, вы можете захотеть различать случаи, когда вы делаете и не хотите трассировки стека, специализируя ваше исключение «ошибка приложения».)
Обратите внимание, что мы все еще разрешаем распространению исключения на main
... по причинам, объясненным в ответе @ skaffman.
И последнее, что усложняет этот вопрос, - это исключения, которые выбрасываются в стек какого-либо потока, отличного от потока main
. Вы, вероятно, не хотите, чтобы исключение было обработано и превращено в System.exit()
в стеке другого потока ... потому что это не даст другим потокам возможности корректно завершить работу. С другой стороны, если вы ничего не делаете, поведение по умолчанию для другого потока просто завершается с необработанным исключением. Если в потоке ничего нет, это может остаться незамеченным. К сожалению, не существует простого решения «один размер подходит всем».