Исключения представляют собой более объектно-ориентированный подход к обработке исключительных потоков выполнения, чем коды возврата. Недостаток кодов возврата является то, что вы должны прийти с «особыми» значениями для обозначения различных типов исключительных результатов, например:
public double calculatePercentage(int a, int b) {
if (b == 0) {
return -1;
}
else {
return 100.0 * (a/b);
}
}
выше метод использует код возврата -1, чтобы указать отказ (потому что он не может делить на ноль). Это будет работать, но ваш код вызова должен знать об этой конвенции, например, это может произойти:
public double addPercentages(int a, int b, int c, int d) {
double percentage1 = calculatePercentage(a, b);
double percentage2 = calculatePercentage(c, c);
return percentage1 + percentage2;
}
Приведенный выше код выглядит хорошо на первый взгляд. Но когда b или d равны нулю, результат будет неожиданным. calculatePercentage вернет -1 и добавит его к другому проценту, который, скорее всего, неверен. Программист, который написал addPercentages, не знает, что в этом коде есть ошибка, пока он не проверит его, и даже тогда, только если здесь действительно проверяется достоверность результатов.
С исключениями вы можете сделать это:
public double calculatePercentage(int a, int b) {
if (b == 0) {
throw new IllegalArgumentException("Second argument cannot be zero");
}
else {
return 100.0 * (a/b);
}
}
Это означает, что код будет компилироваться без обработки Exeption, но он остановится при запуске с некорректными значениями. Это часто является предпочтительным способом, поскольку он оставляет его программисту, если и где обрабатывать исключения в цепочке вызовов метода без необходимости объявлять исключение на каждой промежуточной сигнатуре метода.
Если вы хотите, чтобы заставить программист обработать это исключение можно использовать проверяемое исключение, например:
public double calculatePercentage(int a, int b) throws MyCalculationException {
if (b == 0) {
throw new MyCalculationException("Second argument cannot be zero");
}
else {
return 100.0 * (a/b);
}
}
Обратите внимание, что calculatePercentage должен объявить исключение в своей подписи методы. Проверенное исключение должно быть объявлено таким образом, и вызывающий код должен либо их поймать, либо объявить в своей собственной сигнатуре метода.
Разработчики Java в настоящее время, как правило, согласны с тем, что проверенные исключения являются слишком инвазивными, поэтому большинство API в последнее время тяготеют к неконтролируемым исключениям.
Проверенный исключение выше, может быть определена следующим образом:
общественного класса MyCalculationException расширяет Exception {
public MyCalculationException(String message) {
super(message);
}
}
Создание пользовательского типа исключений, как это имеет смысл, если вы разрабатываете компонент с несколькими классами и методами, которые используются несколькими другими компонентами, и вы хотите, чтобы ваш API (включая обработку исключений) был очень ясным.
(см Throwable class hierarchy)
Проблема заключается в том, что вы не можете покрыть все. – herohuyongtao
Этот вопрос лучше подходит для программистов.stackexchange.com – Incognito
Для крайне примитивных ситуаций ваша стратегия работает и действует. Но в тот момент, когда ситуация усложняется, вы сталкиваетесь с проблемами. Например, в большинстве программ вы не можете просто вывести что-то и выйти прямо посреди чего-то. Также может быть, что просто выводить сообщение об ошибке просто недостаточно. Просто изображение ввода не является человеком, а каким-то датчиком. Тогда, вероятно, система должна реагировать на тот факт, что из этого датчика поступает неправильное значение. Но такая реакция может оказаться невозможной на том же уровне, что и оценка ввода. – arkascha