Looking for java Keywords? Try Ask4Keywords

Java Language Pitfall - «Создание хороших» неожиданных нулей


пример

В StackOverflow мы часто видим такой код в ответах:

public String joinStrings(String a, String b) {
    if (a == null) {
        a = "";
    }
    if (b == null) {
        b = "";
    }
    return a + ": " + b;
}

Часто это сопровождается утверждением, которое является «лучшей практикой» для проверки null чтобы избежать исключения NullPointerException .

Это лучшая практика? Короче: Нет.

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

Что значит для «a» или «b» быть нулевым?

Значение String может быть равно нулю или больше символов, поэтому у нас уже есть способ представления пустой строки. null означает что-то другое, чем "" ? Если нет, то проблематично иметь два способа представления пустой строки.

Был ли null получен из неинициализированной переменной?

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

Указывает ли нуль значение «не знаю» или «отсутствует»?

Иногда null может иметь подлинный смысл; например, что реальное значение переменной неизвестно или недоступно или «необязательно». В Java 8 класс Optional предоставляет лучший способ выразить это.

Если это ошибка (или ошибка дизайна), мы должны «сделать хорошо»?

Одна из интерпретаций кода заключается в том, что мы «делаем хороший» неожиданный null , используя пустую строку на своем месте. Правильная ли стратегия? Было бы лучше позволить NullPointerException , а затем поймать исключение дальше по стеку и зарегистрировать его как ошибку?

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

Является ли это эффективным / хорошим для качества кода?

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

В итоге

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

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