Вопрос-ответ

IllegalArgumentException or NullPointerException for a null parameter? [closed]

Исключение IllegalArgumentException или NullPointerException для параметра null?

У меня есть простой метод установки для свойства и null не подходит для этого конкретного свойства. Я всегда разрывался в этой ситуации: должен ли я использовать IllegalArgumentException или a NullPointerException? Из javadoc оба кажутся подходящими. Есть ли какой-то понятный стандарт? Или это просто одна из тех вещей, которые вы должны делать так, как вам больше нравится, и обе действительно верны?

Переведено автоматически
Ответ 1

Вы должны использовать IllegalArgumentException (IAE), а не NullPointerException (NPE) по следующим причинам:

Во-первых, в NPE JavaDoc явно перечислены случаи, когда NPE подходит. Обратите внимание, что все они выдаются средой выполнения при null ненадлежащем использовании. В отличие от этого, IAE JavaDoc не может быть более понятным: "Выдается для указания того, что методу был передан недопустимый аргумент". Ага, это ты!

Во-вторых, когда вы видите NPE в трассировке стека, что вы предполагаете? Вероятно, кто-то разыменовал a null. Когда вы видите IAE, вы предполагаете, что вызывающий метод в верхней части стека передал недопустимое значение. Опять же, последнее предположение верно, первое вводит в заблуждение.

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

В-четвертых, все остальные неверные данные параметра будут IAE, так почему бы не быть согласованными? Почему недопустимый null настолько особенный, что заслуживает отдельного исключения из всех других типов недопустимых аргументов?

Наконец, я принимаю аргумент, приведенный в других ответах, о том, что части Java API используют NPE таким образом. Однако Java API несовместим со всем, от типов исключений до соглашений об именовании, поэтому я думаю, что простое слепое копирование (вашей любимой части) Java API не является достаточно веским аргументом, чтобы превзойти эти другие соображения.

Ответ 2

Похоже, что IllegalArgumentException вызывается, если вы не хотите, чтобы null было допустимое значение, и NullPointerException было бы выдано, если бы вы пытались использовать переменную, которая оказывается null.

Ответ 3

Стандарт заключается в выбрасывании NullPointerException. Обычно безошибочная "Эффективная Java" кратко обсуждает это в п. 42 (первое издание), п. 60 (второе издание) или п. 72 (третье издание) "В пользу использования стандартных исключений":


"Возможно, все ошибочные вызовы методов сводятся к недопустимому аргументу или недопустимому состоянию, но другие исключения стандартно используются для определенных типов недопустимых аргументов и состояний. Если вызывающий объект передает значение null в каком-либо параметре, для которого значения null запрещены, соглашение предписывает вызывать исключение NullPointerException, а не исключение IllegalArgumentException."


Ответ 4

Я был полностью за выбрасывание IllegalArgumentException для параметров null до сегодняшнего дня, когда я заметил метод java.util.Objects.requireNonNull в Java 7. С помощью этого метода вместо выполнения:

if (param == null) {
throw new IllegalArgumentException("param cannot be null.");
}

вы можете сделать:

Objects.requireNonNull(param);

и он выдаст NullPointerException если параметр, который вы ему передаете, является null.

Учитывая, что этот метод находится в самом разгаре, java.util я считаю его существование довольно убедительным признаком того, что throwing NullPointerException - это "способ ведения дел Java".

Я думаю, что в любом случае я принял решение.

Обратите внимание, что аргументы о жесткой отладке являются фиктивными, потому что вы, конечно, можете предоставить сообщение для NullPointerException, в котором говорится, что было null и почему оно не должно быть null . Точно так же, как с IllegalArgumentException.

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

java exception