Должны ли мы всегда проверять каждый параметр метода в Java на нулевое значение в первой строке? - PullRequest
22 голосов
/ 02 марта 2011

Каждый метод принимает набор значений параметров. Должны ли мы всегда проверять ненулевое значение входных параметров или позволить коду не работать с классическим RunTimeException?

Я видел много кода, где люди на самом деле не проверяют недействительность входных параметров и просто пишут бизнес-логику, используя параметры. Какой самый лучший способ?

void public( String a, Integer b, Object c)
{
  if( a == null || b == null || c == null)
  {
    throw new RunTimeException("Message...");
  }
  .....business logic.....
}

Ответы [ 10 ]

24 голосов
/ 02 марта 2011

Лучший способ - проверять только при необходимости .

Если ваш метод, например, private, и вы знаете, что никто другой не использует его, и вы знаете, что не передаете нулевые значения, нет смысла проверять снова.

Если ваш метод - public, кто знает, что пользователи вашего API попытаются сделать, так что лучше проверьте.

Если в сомнении, отметьте .

Если лучшее, что вы можете сделать, это бросить NullPointerException, то, возможно, не захотите проверять. Например:

int getStringLength(String str) {
  return str.length();
}

Даже если вы отметили null, разумным вариантом было бы бросить NullPointerException, что str.length() подойдет для вас в любом случае.

2 голосов
/ 03 марта 2011

К несчастью, Java может ссылаться на null, и на языке нет способа указать, что это не так.

В общем, да, не составляйте интерпретацию для null и не попадите в ситуацию, когда NPE может быть брошен позже.

JSR305 (теперь неактивный) позволил ваманнотировать параметры, чтобы утверждать, что они не должны быть заданы null s.

void fn(@Nonnull String a, @Nonnull Integer b, @Nonnull Object c) {

Подробно, но это Java для вас.Существуют и другие библиотеки аннотаций и контролеры, которые делают то же самое, но нестандартно.

(Примечание по поводу заглавных букв: когда слова в виде верблюжьих слов в виде "не-вещь", стандарт не должен начинаться с заглавного слова маршрута, если это не имя класса, поэтому nonthing и nonnull.)

Аннотации также фактически не применяют правило, кроме случаев, когда проверяетсязапустить.Вы можете статически включить метод для проверки:

public static <T> T nonnull(T value) {
    if (value == null) {
        throwNPE();
    }
    return value;
}
private static void throwNPE() {
    throw new NullPointerException();
}

Возвращение значения удобно в конструкторах:

import static pkg.Check.nonnull;

class MyClass {
    @Nonnull private final String thing;
    public MyClass(@Nonnull String thing) {
        this.thing = nonnull(thing);
    }
    ...
2 голосов
/ 02 марта 2011

Нет. Принято считать, что параметры не будут равны NULL, а в противном случае будет выдано исключение NullPointerException. Если ваш метод позволяет параметру иметь нулевое значение, вы должны указать это в своем API.

1 голос
/ 06 февраля 2015

Да, публичные методы должны очищать ввод, особенно если неправильный ввод может вызвать проблемы в коде вашего метода. Хорошая идея - быстро потерпеть неудачу; то есть проверьте как можно скорее. В Java 7 добавлен новый класс Objects, который упрощает проверку на нулевые параметры и включает настраиваемое сообщение:

public final void doSomething(String s)
{
  Objects.requireNonNull(s, "The input String cannot be null");
  // rest of your code goes here...
}

Это бросит NullPointerException.

Javadocs для Objects класса: http://docs.oracle.com/javase/7/docs/api/java/util/Objects.html

1 голос
/ 02 марта 2011

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

Каковы бизнес-правила?Допустимо ли значение NULL для поля?Это не?

В любом случае, всегда рекомендуется ПРОВЕРИТЬ пустые значения ЛЮБЫХ параметров перед тем, как вы попытаетесь с ними работать, поэтому вы не получите NullPointerExceptions, когда кто-то передает вам неверные данные.

1 голос
/ 02 марта 2011

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

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

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

0 голосов
/ 02 марта 2011

Если вы не знаете, следует ли вам это делать, скорее всего, вам не нужно это делать.

Источники JDK и книга Джошуа Блоха являются ужасными примерами для подражания, потому что они нацелены на очень различных аудиторий. Сколько из нас пишут публичные API для миллионов программистов?

0 голосов
/ 02 марта 2011

Нет, вы не должны делать это повсеместно.

Мои предпочтения, по порядку, будут:

  1. Сделай что-нибудь разумное с нулем. Разумная вещь, которую нужно сделать, полностью зависит от ситуации, но выбрасывание пользовательского исключения не должно быть вашим первым выбором.
  2. Используйте утверждение для проверки на нулевое значение и тщательного тестирования, исключая любые ситуации, в которых вводится нулевое значение, поскольку - ошибки a.k.a.
  3. Для общедоступных API документируйте, что null недопустим, и дайте ему потерпеть неудачу с NPE.
0 голосов
/ 02 марта 2011

Это зависит от того, что ваш код пытается сделать, и ситуации, в которой вы хотите выбросить Exception.Когда-нибудь вы захотите, чтобы ваш метод всегда выдавал исключение, если ваш метод не сможет правильно работать с нулевыми значениями.Если ваш метод может работать с нулевыми значениями, то, вероятно, нет необходимости выдавать исключение.

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

0 голосов
/ 02 марта 2011

Я не вижу особого смысла в этом. Вы просто копируете поведение, которое вы получаете бесплатно при первой попытке работать с a, b или c.

...