Лучше проверять перед процессом или просто выдает исключение? - PullRequest
0 голосов
/ 16 мая 2011

Рассмотрим этот код:

x = Repo.GetX(13);
Services.Process(x);

Я мог бы проверить, что x равен нулю, прежде чем обрабатывать его, или у меня может быть Services.Process () выдает исключение, если X равно нулю, и использовать блок try / catch,

Какой метод предпочтительнее?

(Или мне следует сделать и то и другое, только в исключительном случае, когда x каким-то образом становится нулевым с момента его поиска до его обработки?)

Ответы [ 4 ]

1 голос
/ 16 мая 2011

Если вы пытаетесь выбрать между:

x = Repo.GetX(13);
try {
    Services.Process(x);
} catch (NullPointerException) {
    System.err.println('x is NULL');
}

или

x = Repo.GetX(13);
if (x != NULL) {
    Services.Process(x);
} else {
    System.err.println('x is NULL');
}

Тогда знайте, что они не означают одно и то же .Первый перехватывает any NullPointerException, выданное Process.Второй обрабатывает только тот случай, когда x сам по себе равен NULL - если Process делает x.foo().bar(), а x.foo() возвращает NULL, он не обрабатывается.

Вы должны выбрать между двумяна какие ошибки вы можете справиться.

В случае, если Services.Process задокументировано для выброса NullPointerException, если и только если x равно NULL, так что (если мы верим в документацию) эти два значения означают одно и то же, тогда я бы сделалвторой.Таким образом, если документация ложная, и в Services.Process есть ошибка, из-за которой она возникает в другой ситуации, мы не будем ошибочно обрабатывать / сообщать об исключении, как если бы x были NULL, хотя на самом деле это не так.

Итак, поймайте и подавьте исключение в двух ситуациях:

  1. Вы знаете, что (такого рода вещи) вызвало ошибку, и вы знаете, что вы можете справиться с этой ситуацией и продолжить независимо.
  2. Для защиты некоторого довольно внешнего уровня кода, такого как цикл обработки событий, от непредвиденных ошибок в программе или среде.В идеале это должно привести к интенсивному ведению журнала, потому что либо система не смогла выполнить то, что вы ожидали (возможно, из-за нехватки ресурсов или неудовлетворенных зависимостей), либо в другом месте есть ошибка в чьем-то коде.

Не ловите только потому, что вы знаете одну ситуацию, которая может вызвать исключение, и справиться с этим, когда такое же исключение может быть вызвано по другим причинам.Я полагаю, что вы могли бы сделать:

x = Repo.GetX(13);
try {
    Services.Process(x);
} catch (NullPointerException) {
    if (x == NULL) {
        System.err.println('x is NULL');
    } else {
        throw;
    }
}

Но в данном случае это кажется мне ненужным многословным: поскольку мы можем заранее проверить, является ли x нулем, мы могли бы также.Однако есть случаи, когда вы ловите исключение, потому что невозможно или просто глупо попытаться заранее предсказать, произойдет ли оно или нет:

String s = Rep.GetString(13);
try {
    f = Float.parseFloat(s);
    System.out.println('is a number');
} catch (NumberFormatException) {
    System.out.println('not a number');
}

Мы могли бы проверить, является ли s - это допустимое число перед вызовом parseFloat, но в основном это будет выполнять ту же самую работу дважды - проверка строки на допустимое число с плавающей точкой во многом аналогична фактическому ее преобразованию.Поэтому имеет смысл перехватить это исключение - мы знаем, что это значит, мы знаем, что с этим делать, мы не могли бы реально предотвратить это.

(Или вы можете использовать DecimalFormat.parse, которыйне бросает вообще)

1 голос
/ 16 мая 2011

Как обычно, правильный ответ для такого рода проблем: Это зависит.

Наилучшим способом, если это возможно, является определение границы, где выполняется такая проверка. Все внутри границы может полагаться на то, что все будет хорошо инициализировано. Если все еще NULL подкрадывается, взрыв с NPE очень уместен.

В целом проверка предварительных условий перед попыткой выполнения реальной работы делает код намного чище.

Если вы не можете установить эти границы в своей системе, возникает вопрос: что происходит, когда x равен NULL, а полученное исключение не обрабатывается, какие у вас варианты, когда вы его не обрабатываете?

Во многих случаях вы все равно ничего не можете с этим поделать, и тогда просто разрешить исключению подняться в стек вызовов до пользовательского интерфейса (или интерфейса службы или чего-либо еще).

Но иногда вызывающий процесс с нулевым аргументом разрушает аппаратную часть, убивает пациента или иным образом очень неприятен. В этом случае: проверьте прямо перед потенциальным вредным действием.

0 голосов
/ 16 мая 2011

Для обработки исключений следует использовать обработку исключений.

Если вы считаете, что x никогда не должно иметь значение null, используйте оператор try / catch.Если x в некоторых случаях будет иметь значение null, то оператор if.

0 голосов
/ 16 мая 2011

Куда лучше проверить. Обработка исключений обычно обходится дорого.

...