Я написал функцию, которая запрашивает ввод у пользователя, пока пользователь не введет положительное целое число (натуральное число). Кто-то сказал, что я не должен генерировать и перехватывать исключения в моей функции и должен позволять вызывающей стороне моей функции обрабатывать их.
Интересно, что другие разработчики думают об этом. Я также, вероятно, неправильно использую исключения в функции. Вот код на Java:
private static int sideInput()
{
int side = 0;
String input;
Scanner scanner = new Scanner(System.in);
do {
System.out.print("Side length: ");
input = scanner.nextLine();
try {
side = Integer.parseInt(input);
if (side <= 0) {
// probably a misuse of exceptions
throw new NumberFormatException();
}
}
catch (NumberFormatException numFormExc) {
System.out.println("Invalid input. Enter a natural number.");
}
} while (side <= 0);
return side;
}
Я заинтересован в двух вещах:
- Должен ли я позволить вызывающей стороне беспокоиться об исключениях? Смысл функции заключается в том, что она выслеживает пользователя, пока пользователь не введет натуральное число. Смысл функции плохой? Я говорю не о пользовательском интерфейсе (пользователь не может выйти из цикла без правильного ввода), а о циклическом вводе с обработанными исключениями.
- Вы сказали бы, что оператор throw (в данном случае) является неправильным использованием исключений? Я мог бы легко создать флаг для проверки правильности номера и вывести предупреждающее сообщение на основе этого флага. Но это добавит больше строк в код, и я думаю, что он отлично читается как есть.
Дело в том, что я часто пишу отдельную функцию ввода. Если пользователь должен ввести число несколько раз, я создаю отдельную функцию для ввода, которая обрабатывает все исключения и ограничения форматирования.
exceptions
USR
источник
источник
Ответы:
Смысл исключения состоит в том, что он позволяет методу сообщать вызывающему абоненту, который вошел в состояние, в котором он не может нормально продолжаться, без принуждения вставлять код ошибки в возвращаемое значение.
В вашем случае ваш метод точно знает, что делать, если входное значение не больше 0. Единственная причина, по которой вы сохраняете строки, заключается в том, что вы вызываете то же исключение, которое вы получили бы, если бы входное значение не было числом. Однако создаваемое вами исключение неправильно отображает, почему вашему коду не нравится ввод. Если кто-то еще придет и увидит этот код, ему придется потратить дополнительное время, пытаясь понять, как все работает.
источник
Это плохое использование исключений. Начнем с того, что неположительное число не является исключением формата.
Зачем вообще использовать исключения? Если вы знаете, что ввод запрещен, просто не прерывайте цикл, пока не получите действительный ввод от пользователя, что-то вроде следующего:
источник
Integer.parseInt()
бросает,NumberFormatException
если не может проанализировать предоставленный строковый аргумент. Вам не нужно (и вы не сможете) бросить исключение самостоятельно.Integer.parseInt()
метод сгенерирует для вас исключение, если оно произойдет, вы не сможете сами его сгенерировать, поскольку оно уже было сгенерировано.Отлавливать исключения можно только в том случае, если вы собираетесь сделать что-то, имеющее отношение к текущему вызову метода; т. е. очистка, логика сбоев и т. д. В этом случае перехват просто отправляет сообщение на консоль, оно не относится к методу sideInput, поэтому его можно обрабатывать дальше по цепочке вызовов / стеку.
Здесь можно избавиться от try / catch и просто задокументировать вызов метода:
Еще нужно обработать это исключение дальше по цепочке вызовов / стеку!
источник
Вы не должны бросать и перехватывать одно и то же исключение в методе, я даже думаю, что блок catch будет перехватывать то же исключение, которое вы генерируете, так что вы на самом деле его не выбрасываете.
Если
parseInt
был успешным, то это не такNumberFormatException
.если сторона меньше нуля, вы должны бросить
NegativeSideLengthException
;Создайте пользовательское исключение для бизнеса с именем
NegativeSideLengthException
Затем
sideInput
выдает NegativeSideLengthExceptionВы можете даже (если хотите) добавить еще один блок catch для перехвата
NegativeSideLengthException
и не иметь метода, который его выбрасывает.Флаги не являются хорошим способом обработки исключений.
источник
Исключения - довольно кошмарные вещи, они приносят больше сложностей, чем решают.
Во-первых, если вы не перехватываете свои исключения, вызывающая сторона может делать только то
on error resume next
, что через неделю даже вы не узнаете, что может выдать ваша функция и что с ней делать:По сути, если вы поймали их, вы должны очень хорошо понимать контракты и гарантии исключений. Это редко случается в реальном мире. А также ваш код будет трудно читать.
Кроме того, забавно то, что если у вас действительно есть шанс обработать исключения, вам нужен настоящий язык RAII, что-то вроде юмора, поскольку Java и .NET - это все об исключениях ...
Повторяю это еще раз, но ...:
http://blogs.msdn.com/b/oldnewthing/archive/2004/04/22/118161.aspx
http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx
http://www.joelonsoftware.com/items/2003/10/13.html
источник
: throw(thisexception, thatexception)
совершенно неправильны и никогда не должны использоваться, потому что в противном случае вы получите непредвиденное исключение.catch
. Хотя игнорируемое возвращаемое значение невозможно найти - оно может быть идентифицировано только путем построчного просмотра кода. И последнее, но не менее важное, конструкторы не имеют возвращаемых значений, это основная причина использования исключений.