Не используйте ноль, используйте Необязательный
Как вы указали, одной из самых больших проблем nullв Java является то, что он может использоваться везде или, по крайней мере, для всех ссылочных типов.
Невозможно сказать, что может быть, nullа что нет.
Java 8 предоставляет гораздо лучше картина: Optional.
И пример из Oracle:
String version = "UNKNOWN";
if(computer != null) {
Soundcard soundcard = computer.getSoundcard();
if(soundcard != null) {
USB usb = soundcard.getUSB();
if(usb != null) {
version = usb.getVersion();
}
}
}
Если каждый из них может или не может вернуть успешное значение, вы можете изменить API на Optionals:
String name = computer.flatMap(Computer::getSoundcard)
.flatMap(Soundcard::getUSB)
.map(USB::getVersion)
.orElse("UNKNOWN");
Благодаря явному кодированию опциональности в типе ваши интерфейсы будут намного лучше, а ваш код - более чистым.
Если вы не используете Java 8, вы можете посмотреть com.google.common.base.Optionalв Google Guava.
Хорошее объяснение от команды Guava: https://github.com/google/guava/wiki/UsingAndAvoidingNullExplained
Более общее объяснение недостатков, связанных с нулем, с примерами на нескольких языках: https://www.lucidchart.com/techblog/2015/08/31/the-worst-mistake-of-computer-science/
@Nonnull, @Nullable
Java 8 добавляет эти аннотации, чтобы помочь инструментам проверки кода, таким как IDE, выявлять проблемы. Они довольно ограничены в своей эффективности.
Проверьте, когда это имеет смысл
Не пишите 50% кода, проверяющего ноль, особенно если нет ничего разумного, что ваш код может сделать со nullзначением.
С другой стороны, если это nullможно использовать и что-то значить, обязательно используйте его.
В конечном счете, вы, очевидно, не можете удалить nullиз Java. Я настоятельно рекомендую заменять Optionalабстракцию всякий раз, когда это возможно, и проверять в nullдругих случаях, что вы можете сделать что-то разумное с этим.