Когда выполнение пустого указателя регистрируется в коде Java, и Вы бросаете IllegalArgumentExceptions для нулевых значений, какой шаблон сообщения Вы используете?
Мы склонны использовать что-то вроде этого
public User getUser(String username){
if (username == null){
throw new IllegalArgumentException("username is null");
}
// ...
}
Что лучше: "является пустым", или "было пустым", и почему?
Для меня "пустые" более естественные чувства.
Поскольку исключение
выбрасывается из-за неудачной проверки предварительного условия, я думаю, что вместо того, чтобы просто констатировать факт, вы должны указать требование , которое было нарушено.
То есть, вместо «имя пользователя пустое»
, скажите «имя пользователя не должно быть пустым»
.
В качестве подсказки вы можете использовать одну из многих библиотек, разработанных для облегчения проверки предварительных условий. Во многих кодах Guava используются com.google.common.base.Preconditions
Простые статические методы, вызываемые в начале ваших собственных методов для проверки правильности аргументов и состояния.Это позволяет использовать такие конструкции, как
if (count <= 0) { выбросить новое исключение IllegalArgumentException ("должно быть положительным:" + счетчик); }
следует заменить более компактным
checkArgument (count> 0, «должно быть положительным:% s», count);
Здесь более уместно то, что в нем есть checkNotNull
, что позволяет вам просто написать:
checkNotNull(username, "username should not be null");
Обратите внимание, как естественно читается приведенный выше код, с подробным сообщением, явно указывающим требование , что было нарушено.
Альтернатива изложения фактов более неудобна:
// Awkward!
checkArgument(count > 0, "is negative or zero: %s", count);
checkNotNull(username, "username is null");
Более того, это также потенциально менее полезно, поскольку клиент может уже знать об этом факте, и исключение не помогает им выяснить, что на самом деле требования есть.
IllegalArgumentException
vs NullPointerException
В то время как исходный код выдает IllegalArgumentException
на аргументах null
, предварительные условия Гуавы Preconditions.
] вместо этого выбрасывает NullPointerException
.
Это соответствует руководству, установленному API:
NullPointerException
: приложения должны генерировать экземпляры этого класса, чтобы указать на другое незаконное использование объектаnull
.
Кроме того, вот цитата из Эффективное 2-е издание Java: Правило 60: Поддерживайте использование стандартных исключений :
Возможно, все ошибочные вызовы методов сводятся к недопустимому аргументу или недопустимому состоянию, но другие исключения стандартно используются для определенных видов недопустимых аргументов и состояний.Если вызывающий передает
null
в каком-либо параметре, для которого запрещены нулевые значения, соглашение требует, чтобы было выброшено исключениеNullPointerException
, а неIllegalArgumentException
.
имеет значение NULL , поскольку аргумент все еще имеет значение NULL ..
Однако почему бы просто не выбросить исключение NullPointerException без сообщения?
Я был бы склонен написать следующее:
public User getUser(String username) {
if (username.length() == 0) {
throw new IllegalArgumentException("username is empty");
}
// ...
}
Это убивает двух зайцев одним выстрелом. Во-первых, он обнаруживает случай, когда имя пользователя представляет собой пустую строку, что (в качестве аргумента), как я предполагаю, является ошибкой. Во-вторых, если параметр равен null
, попытка отправить вызов длины выдаст исключение
NullPointerException
.
Для записи, ожидаемое исключение для неожиданного null
равно NullPointerException
. Если ваша основная причина, по которой вы его не используете, заключается в том, что у NPE обычно нет сообщения, запишите его так:
public User getUser(String username){
if (username == null){
throw new NullPointerException("username is null");
}
if (username.length() == 0) {
throw new IllegalArgumentException("username is empty");
}
// ...
}
Зачем здесь использовать NPE? Потому что NPE почти всегда указывают на другой тип проблемы по сравнению с другими типами ошибок проверки аргументов; например поле или ячейка массива, которые не были инициализированы, или «необязательное» значение, которое не обрабатывается должным образом.
Наконец, ответ на вопрос:
Что лучше:
«пусто»
или«было нулем»
, и почему?
Это вопрос мнения, но я бы написал «равно нулю»
.
Я бы предложил сказать
if (userName == null) {
throw new IllegalArgumentException("username == null");
}
так как это настолько фатально, что программист должен посмотреть на это в любом случае. Ссылка на фрагмент кода в сообщении об исключении - это самое лаконичное, что я могу себе представить.