Как уведомить программиста о пустом аргументе? - PullRequest
4 голосов
/ 21 февраля 2012

Итак, я работаю над созданием класса, в котором, если определенные аргументы определенных методов являются нулевыми, либо метод (или объект в целом) не будет работать.

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

Я видел несколько примеров того, что я описал, где они выдают IllegalArgumentExceptionкогда параметр имеет значение null.

Вот разница, представьте себе, что someObject как-то жизненно важен для метода:

public void doSomething(SomeClass someObject) {
    if (someObject == null) throw new IllegalArgumentException("someObject is null");
    ...
}

Таким образом, программист понимает, что он или она нарушил контрактподразумевается Javadoc (независимо от того, указано ли это явно).

Это хорошая практика, или даже разумный поступок?

Быстрое редактирование / Боковая панель:

Что лучше сказать в сообщении об исключении?

Лучше указать, что "пошло не так":

someObject равен нулю

Или лучше заявить, что что-то "пошло не так" и, как правило, подразумевать причину (и, в конечном итоге, решение):

someObject не можетбыть нулевым

Или есть лучшая альтернатива?

Ответы [ 5 ]

5 голосов
/ 21 февраля 2012

Используйте IllegalArgumentException вместо разрешения NullPointerException, чтобы вы могли обнаружить ошибку как можно раньше. Вы можете выполнить ту же проверку и самим бросить NullPointerException, но это вопрос семантики.

Немедленно выдав ошибку, она помогает вам или другому разработчику поймать ошибку, прежде чем что-либо еще произойдет. Если ваш метод не использует аргумент сразу (например, в установщике), тогда проблема может быть результатом какой-то совершенно другой операции.

Если вы не знакомы с ней, фантастическая книга под названием Прагматичный программист содержит совет, который я пытаюсь подчеркнуть здесь:

Время 32: ранний сбой

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

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

public void doSomething(SomeClass someObject) {
    assert someObject != null    
    ...
}

Если утверждение не выполнено, выдается ошибка. Хотя это можно отключить с помощью параметров компилятора, это хорошая практика во время разработки.

4 голосов
/ 21 февраля 2012

Я бы сказал, что стандартная документированная практика - просто использовать NullPointerException.

  1. Это явно используется во многих @throws Javadocs для документирования случая, когда аргумент null и ему не разрешено быть (Reader.read(CharBuffer), String.contains(CharSequence) и многое, многое другое)
  2. Рекомендуется в уважаемых правилах кодирования (например, Bloch рекомендует использовать его в эффективной Java).
  3. Сам класс говорит, что он должен быть явно брошен:

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

  4. Это то, что Гуава Preconditions выбрасывает для checkNotNull, и они знают дизайн библиотеки Java.
  5. Использование NullPointerException не мешает вам выдать хорошее сообщение об ошибке, описывающее исключение. Таким образом вы устанавливаете такие трассировки стека отдельно от стандартной трассировки стека NPE.
Если вы действительно хотите отклониться от стандарта, вы можете использовать IllegalArgumentException, но в этот момент я бы пошел еще дальше и создал подкласс с именем NullArgumentException.

Редактировать

Говоря о предварительных условиях, вы, кажется, на пути к эффективному использованию исключений времени выполнения для проверки значений и инвариантов. Я настоятельно рекомендую вам просто использовать библиотеку предварительных условий Guava, чтобы стандартизировать и упростить это. Ваш пример просто сводится к:

public void doSomething(SomeClass someObject) {
    Preconditions.checkNotNull(someObject, "someObject cannot be null");
    //...
}
1 голос
/ 21 февраля 2012

Оба подхода разумны.Если ваш Javadoc говорит, что прохождение null приведет к NPE, а пользователь вашего API получит NPE, то мне кажется, что функция работает так, как объявлено!

Я считаю, что NPEпроще всего, когда аргумент должен использоваться в этом методе.Если вы собираетесь сохранить ссылку на потом (например, в конструкторе), то IllegalArgumentException имеет немного больше смысла.Другими словами, бросить NPE, если это происходит естественным образом, и бросить IAE, если оно спасет будущий NPE.

1 голос
/ 21 февраля 2012

Вы можете использовать либо. Просто документируйте свой выбор и будьте последовательны. Если клиенты, скорее всего, будут использовать вашу библиотеку с другой, то согласие с этим, вероятно, также поможет клиентам.

0 голосов
/ 21 февраля 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...