Это должно хорошо бросить NullPointerException программно?

Когда существует постусловие, то возвращаемое значение метода не должно быть пустым, что может быть сделано?

Я мог сделать

assert returnValue != null : "Not acceptable null value";

но утверждения могли быть выключены!

Так это хорошо, чтобы сделать

if(returnValue==null)
      {
           throw new NullPointerException("return value is null at method AAA");
      }

?

Или лучше использовать пользовательское исключение (как NullReturnValueException) для такого условия?

44
задан Cœur 4 April 2017 в 12:13
поделиться

12 ответов

Я не вижу проблемы в том, чтобы бросать NPE как можно раньше, пока JVM не сделала это за вас - в частности, для нулевых аргументов. Кажется, по этому поводу ведутся дебаты, но в библиотеках Java SE есть много примеров, которые делают именно это. Я не вижу, почему NPE должен быть святым в том аспекте, что вы не можете бросить его сами.

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

Как бы вы вообще это задокументировали? "Этот метод выбрасывает NullPointerException, если возвращаемое значение неожиданно равно null"? Не объясняя, как это может произойти? Нет, я бы использовал здесь утверждение. Исключения должны использоваться для ошибок, которые могут произойти - не для того, чтобы покрывать вещи, которые могут произойти, если внутри метода что-то не так, потому что это никому не поможет.

41
ответ дан 26 November 2019 в 21:37
поделиться

Бросать это исключение - не лучшая практика в некоторых случаях, и мне интересно, почему, если вы уже поймали его с помощью оператора if?

if(returnValue==null)

-1
ответ дан 26 November 2019 в 21:37
поделиться

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

0
ответ дан 26 November 2019 в 21:37
поделиться

IMO вы никогда не должны вручную бросать NullPointerException. Вызывающий метод не будет знать, настоящее или ручное NullPointerException без проверки описания. В данном случае похоже, что вы хотите бросить собственное исключение, которое ближе соответствует проблеме, чтобы вызывающий метод мог правильно восстановить это исключение. Возможно, PostConditionException будет достаточно универсальным для многих обстоятельств.

0
ответ дан 26 November 2019 в 21:37
поделиться

Часто бывает действительно хорошей идеей бросить NPE до того, как логика станет настолько глубокой, что вызывающему программисту будет трудно определить, что было нулевым. Хорошим примером являются методы addListener ().

Несмотря на неинформированные отрицательные голоса, в JDK есть много методов, которые делают именно это.

1
ответ дан 26 November 2019 в 21:37
поделиться

В JavaDoc для исключения NullPointerException указано:

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

 * Вызов метода экземпляра нулевого объекта.
* Доступ или изменение поля нулевого объекта.
* Принимая длину нуля, как если бы это был массив.
* Доступ или изменение пустых слотов, как если бы это был массив.
* Выбрасывание null, как если бы это было значение Throwable.

Приложения должны генерировать экземпляры этот класс для обозначения других незаконных использование нулевого объекта.

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

Если, напротив, вы считаете, что условие публикации может быть нарушено, было бы неплохо включить дополнительную отладочную информацию, такую ​​как аргументы, с которыми был вызван метод.

3
ответ дан 26 November 2019 в 21:37
поделиться

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

Если вы проверите параметры вашего метода в самом начале, бросить новое исключение IllegalArgumentException ("foo == null") тоже приемлемо для меня.

5
ответ дан 26 November 2019 в 21:37
поделиться

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

catch (NullPointerException npe) {
  if (npe.getMessage().equals("Null return value from getProdByCode") {
    drawToUser("Unable to find a product for the product type code you entered");
  } 
}

Это верный индикатор, что вы делаете что-то не так. Поэтому, если возвращаемое значение null является индикатором некоторого состояния системы, с которым вы действительно можете взаимодействовать, используйте исключение, которое сообщает это состояние. Я могу придумать не так много случаев, когда имеет смысл обнулять ссылку, просто чтобы отбросить нулевой указатель. Обычно следующая строка кода все равно отбрасывала бы нулевой указатель (или что-то более информативное)!

7
ответ дан 26 November 2019 в 21:37
поделиться

В книге, которую я назвал О'Рейли «Java in A Nutshell» , написанная экспертом, перечислено это определение для NullPointerException:

Сигнализирует о попытке доступа к полю или вызвать метод нулевого объекта.

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

1
ответ дан 26 November 2019 в 21:37
поделиться

Если вы описываете контракт метода, в котором возвращаемое значение не может быть null, то вам лучше убедиться, что вы не возвращаете null. Но это вовсе не исключение NullPointerException. Если значение, которое вы должны вернуть, равно null, то очевидно, что вызывающая сторона либо предоставила вам плохие аргументы (IllegalArgumentException), либо вы находитесь в недопустимом состоянии (IllegalStateException), либо произошло какое-то другое, гораздо более значимое исключительное состояние, отличное от NullPointerException (которое обычно указывает на ошибку программирования).

3
ответ дан 26 November 2019 в 21:37
поделиться

Я бы рекомендовал вам никогда не бросать NullPointerException самостоятельно.

Основная причина не делать этого, как говорит Thorbjørn Ravn Andersen в комментарии ниже, заключается в том, что вы не хотите смешивать "настоящие, плохие NPE" с NPE, брошенными намеренно.

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

Другой (более современный, имхо) вариант - использовать аннотацию @NotNull рядом с аргументом. Вот статья об использовании аннотации @NotNull.

Как я уже говорил, могут быть случаи, когда выброс NPE не смутит ни вас, ни ваших товарищей по команде: Причина NPE должна быть ясна и узнаваема.

Например, если вы используете библиотеку с модулем предусловий, как Guava, то я считаю использование checkNotNull()-подобных методов предпочтительным способом борьбы с незаконно переданными нулями.

checkNotNull(arg, msg) бросает NPE, но из стек-трейса ясно, что он был произведен Preconditions.checkNotNull() и, таким образом, это не неизвестная ошибка, а скорее ожидаемое поведение.

61
ответ дан 26 November 2019 в 21:37
поделиться

Учитывая, что NullPointerException является идиоматическим способом общения неожиданное нулевое значение в Java, я бы порекомендовал вам выбросить стандартное NullPointerException , а не доморощенное. Также имейте в виду, что принцип наименьшего удивления предполагает, что вы не изобретаете свой собственный тип исключения для случая, когда существует системный тип исключения.

Утверждения хороши для отладки, но не годятся, если вам нужно обрабатывать определенные условия, так что это не совсем хороший способ обрабатывать состояние ошибки.

28
ответ дан 26 November 2019 в 21:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: