Нужно ли всегда проверять аргументы на null

165
16 сентября 2017, 23:14

Здравствуйте! Есть такой вот вопрос - нужно ли всегда поверять аргументы на null? наподобие:

public void someMethod(Object someObject) {
    if(someObject == null) {
        throw new NullPointerException();
    }
}

Просто исключение выкинет и так.

Answer 1

Как раз-таки проверять на null нужно, чтобы таких исключений не было.
Например, вы вытаскиваете пользователя по его id из базы:

User user = userRepository.findOne(id);

После этого вы что-то хотите сделать с этим пользователем, допустим вывести на консоль его имя:

System.out.println(user.getName());

Теперь представим, что в базе данных нет пользователя с заданным id. Что произойдет?
Переменная user будет ссылаться на null. И как только мы попытаемся вызвать метод у null, выбросится NullPointerException. А так как это RuntimeException, то он выбросится в процессе работы программы, что не есть хорошо, потому что если его не обработать, это может привести к остановке приложения.
Вообще RuntimeException не следует ловить и выбрасывать самостоятельно (в обычной практике). Вместо этого следует писать такой код, чтобы эти исключения не возникали.
Например прежде, чем вывести имя пользователя, мы можем проверить его на null:

if (user == null) {
    System.out.println("Пользователь с данным id отсутствует");
}

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

Answer 2

Смотрите.

Для каждой переменной вы должны знать, она имеет право быть null в вашей программе или нет. Это центральное соображение.

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

Да, и если значение приходит извне вашего модуля — например, это входной параметр, который не должен быть равен null — вы всё равно должны проверить «на входе», один раз, и в случае чего бросить исключение, потому что вызывающий код может и ошибиться.

Если к вам приходит не параметр, а вы вызываете чужой метод и берёте его возвращаемое значение, и в документации указывается, что этот метод не возвращает null, обычно дополнительные проверки не устраивают, т. к. возвращённый null — баг на стороне чужого модуля. Впрочем, если вы не доверяете коду чужого модуля, то можно добавить проверки тоже.

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

Что считать здесь «модулем», зависит от вас. Часто это один или несколько тесно связанных классов. Но вы можете сделать модуль и крупнее (вам придётся больше держать в голове, но меньше писать обвязочного кода), или мельче, как вам удобно.

READ ALSO
Переделать код из Java в Delphi

Переделать код из Java в Delphi

Требуется скопировать небольшую функцию с Java (Android Studio) на Delphi, для этого необходимо функцию эту переделать немного так как синтаксис отличаетсяСтолкнулся...

178
Обфускация Java приложения

Обфускация Java приложения

У меня есть старенький лаунчер для игрыНо там очень хлипкая защита

174
Spring Security And OAuth2

Spring Security And OAuth2

На проекте используется Spring Security, стандартная форма логинаСейчас еще нужно дабавить возможность авторизации через Azure AD(с помощью протокола...

167
Java Sqlitte передача аргументов в запрос

Java Sqlitte передача аргументов в запрос

Обьясните почему так не работает:

199