Что является более эффективным в Java: проверять неправильные значения, предотвращать исключения или допускать их возникновение и перехватывать их?
Вот два блока примера кода, чтобы проиллюстрировать эту разницу:
void doSomething(type value1) {
ResultType result = genericError;
if (value1 == badvalue || value1 == badvalue2 || ...) {
result = specificError;
} else {
DoSomeActionThatFailsIfValue1IsBad(value1);
// ...
result = success;
}
callback(result);
}
против
void doSomething(type value1) {
ResultType result = genericError;
try {
DoSomeActionThatFailsIfValue1IsBad(value1);
// ...
result = success;
} catch (ExceptionType e) {
result = specificError;
} finally {
callback(result);
}
}
С одной стороны, вы всегда делаете сравнение. С другой стороны, я, честно говоря, не знаю, что делают внутренние компоненты системы, чтобы сгенерировать исключение, сгенерировать его, а затем вызвать предложение catch. Кажется, что он менее эффективен, но если он не добавляет накладных расходов в случае отсутствия ошибок, то в среднем он более эффективен. Что он? Это добавляет подобную проверку в любом случае? Это проверка там в неявном коде, добавленном для обработки исключений, даже с дополнительным уровнем явной проверки? Возможно, это всегда зависит от типа исключения? Что я не рассматриваю?
Давайте также предположим, что все "плохие значения" известны - это очевидная проблема. Если вы не знаете всех неправильных значений - или список слишком длинный и нерегулярный - тогда обработка исключений может быть единственным способом.
Итак, каковы плюсы и минусы каждого и почему?
Дополнительные вопросы для рассмотрения:
- Как изменится ваш ответ, если значение будет "плохим" (будет вызывать исключение) большую часть времени?
- Сколько из этого будет зависеть от особенностей используемой виртуальной машины?
- Если бы тот же вопрос был задан для языка X, был бы ответ другим? (Который, в более общем плане, спрашивает, можно ли предположить, что проверка значений всегда более эффективна, чем полагаться на обработку исключений просто потому, что это добавляет больше накладных расходов текущими компиляторами / интерпретаторами.)
- (Новое) Вызывание исключения происходит медленно. Есть ли в блоке try издержки, даже если исключение не выдается?
Сходства на SO:
- Это похоже на пример кода в этого ответа , но утверждает, что они похожи только в концепции, а не в скомпилированной реальности.
- Посылка похожа на этот вопрос , но, в моем случае, запрашивающая сторона задачи (например, "Something") не является вызывающей стороной метода (например, "doSomething") (таким образом, нет возвращается).
И этот очень похож, но я не нашел ответа на свой вопрос.
И похоже на слишком много других вопросов для перечисления, кроме:
Я не спрашиваю о передовой теоретической практике. Я спрашиваю больше о производительности и эффективности во время выполнения (что должно означать, что для конкретных случаев есть ответы, не связанные с мнением), особенно на платформах с ограниченными ресурсами. Например, если единственным плохим значением является просто нулевой объект, было бы лучше / эффективнее проверить это или просто попытаться использовать его и поймать исключение?