В Java, что более рекомендуется и почему? Оба типа будут генерировать исключения, поэтому обработка их одинакова. assert
немного короче, но я не уверен, насколько это важно.
public void doStuff(Object obj) {
assert obj != null;
...
}
против
public void doStuff(Object obj) {
if (obj == null) {
throw new IllegalArgumentException("object was null");
}
...
}
java
exceptions
conventions
Daenyth
источник
источник
obj.hashCode()
Вместо этого я предпочитаю простой ;-)Ответы:
BEWARE!
Утверждения удаляются во время выполнения, если вы явно не укажете «включить утверждения» при компиляции кода. Утверждения Java не должны использоваться в производственном коде и должны быть ограничены частными методами (см. « Исключение против утверждения» ), поскольку ожидается, что частные методы будут известны и будут использоваться только разработчиками. Также
assert
выдает AssertionError, котораяError
не распространяетсяException
и которая обычно указывает на то, что у вас есть очень ненормальная ошибка (например, «OutOfMemoryError», с которой трудно восстановиться, не так ли?), Которую вы не должны лечить.Удалите флаг «включить утверждения» и проверьте с помощью отладчика, и вы увидите, что вы не будете вмешиваться в вызов вызова IllegalArgumentException ... так как этот код не был скомпилирован (опять же, когда удаляется «ea»)
Лучше использовать вторую конструкцию для открытых / защищенных методов, и если вы хотите что-то, что делается в одной строке кода, есть по крайней мере один из известных мне способов. Я лично использую класс Spring Framework , в
Assert
котором есть несколько методов для проверки аргументов и которые выдают «IllegalArgumentException» при сбое. В основном, что вы делаете:... Который на самом деле будет выполнять тот же код, который вы написали во втором примере. Есть несколько других полезных методов, таких как
hasText
,hasLength
там.Я не люблю писать больше кода, чем необходимо, поэтому я счастлив, когда сокращаю количество написанных строк на 2 (2 строки> 1 строка) :-)
источник
java -ea
и программно. @Jalayn Я думаю, что наличие утверждений в производственном коде совершенно правильно, так как они полезны для отладки в полевых условияхjava -ea
.Objects.requreNonNull
Вам нужно использовать исключение. Использование утверждения было бы неправильным использованием этой функции.
Непроверенные исключения предназначены для обнаружения ошибок программирования пользователей вашей библиотеки, а утверждения предназначены для обнаружения ошибок в вашей собственной логике. Это отдельные вопросы, которые не следует смешивать.
Например, утверждение
означает «Я знаю, что каждый путь кода, приводящий к этому утверждению, гарантирует, что
myConnection
он подключен; если приведенный выше код не смог установить действительное соединение, он должен был вызвать исключение или возврат до достижения этой точки».С другой стороны, чек
означает, что «вызов моей библиотеки без установления соединения является ошибкой программирования».
источник
Если вы пишете функцию, которая не допускает
null
в качестве допустимого значения параметра, вы должны добавить@Nonnull
аннотацию к сигнатуре и использовать ее,Objects.requireNonNull
чтобы проверить, является ли аргумент аргументом,null
и бросить a,NullPointerException
если он есть.@Nonnull
Аннотации для документации и будут предоставлять полезные предупреждения во время компиляции в некоторых случаях. Это не мешаетnull
быть переданным во время выполнения.Обновление:
@Nonnull
аннотации не является частью стандартной библиотеки Java. Вместо этого существует множество конкурирующих стандартов от сторонних библиотек (см. Какую аннотацию @NotNull Java следует использовать? ). Это не значит, что это плохая идея, просто это не стандартно.источник
Objects.requireNonNull()
, что было новым для меня. Вы знаете, есть ли где-нибудь похожий метод requireTrue () или requireEqual ()? Ничего против Spring's Assert, но не все этим пользуются.Objects.requireNonNull()
предназначен для проверки аргументов. Если аргумент должен бытьtrue
или равен чему-то, то аргумент бессмыслен. Для случаев ошибок , отличных от незаконных аргументов, вы должны , что более точно описывает ошибку. Есть также JUnit, но это для тестов.throw
Exception
Assert
Objects.requireTrue(x >= 0.0);
или для некоторого хэша,Objects.requireEquals(hash.length == 256)
Я всегда предпочитаю бросать IllegalArgumentException поверх утверждений.
Утверждения используются в основном в JUnit или других инструментах тестирования для проверки / подтверждения результатов тестирования. Поэтому другим разработчикам может показаться, что ваш метод является тестовым.
Также имеет смысл выдать исключение IllegalArgumentException, если метод получил недопустимый или неподходящий аргумент . Это более соответствует соглашению об обработке исключений, которому следуют разработчики Java.
источник
IMO второй немного лучше, потому что он приносит больше информации и может быть расширен (например, путем расширения класса исключений), чтобы быть еще более информативным, также он не использует отрицательное сравнение, которое легче понять.
источник
Я не часто использую aserts, но общий подход с Lombock @NonNull: https://projectlombok.org/features/NonNull
Реализация Lombok: импорт lombok.NonNull;
Версия Java:
Lombok - действительно неплохая библиотека, которую я использую везде
источник