Необязательный против нуля. Какова цель Необязательного в Java 8?

В Java 8 вы можете вернуть Optional вместо null. В документации на Java 8 указано, что необязательный параметр "Объект контейнера, который может содержать или не содержать ненулевое значение. Если значение присутствует, isPresent() вернет true и get() вернет значение."

На практике, почему это полезно? Кроме того, существует ли случай, когда использование null было бы предпочтительным? Как насчет производительности?

Ответы

Ответ 1

На практике, почему это полезно?

Например, скажем, у вас есть этот поток целых чисел, и вы делаете фильтрацию:

int x = IntStream.of(1, -3, 5)
                 .filter(x -> x % 2 == 0)
                 .findFirst(); //hypothetical assuming that there no Optional in the API

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

Предположим, что в API не будет необязательного. В этом случае, что должно findFirst вернуться?

Единственным возможным способом могло бы стать исключение, такое как NoSuchElementException, что является IMO довольно раздражающим, поскольку я не думаю, что это должно остановить выполнение вашей программы (или вам придется поймать исключение, не очень удобно), и критерии фильтрации могут быть более сложными, чем это.

С помощью Optional, до вызывающего, чтобы проверить, является ли Optional пустым или нет (например, если ваше вычисление привело к значению или нет).

С ссылочным типом вы также можете вернуть null (но null может быть возможным значением в случае, если вы фильтруете только значения null, поэтому вернемся к случаю исключения).

Что касается не-потоковых обычаев, в дополнение к предотвращению NPE, я думаю, что это также помогает разрабатывать более явный API, говорящий, что значение может присутствовать или нет. Например, рассмотрим этот класс:

class Car {
   RadioCar radioCar; //may be null or not 
   public Optional<RadioCar> getRadioCar() {
        return Optional.ofNullable(radioCar);
   }
}

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

Ответ 2

Когда Java была впервые разработана, обычной практикой было использование специального значения, обычно называемого null, чтобы указать особые обстоятельства, например, я не мог найти то, что вы искали. Эта практика была принята Java.

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

Современное отношение - использовать специальный объект, который может или не может содержать значение. Таким образом, вы можете безопасно создать одно и просто не заполнить его ничем. Здесь вы видите, что Java 8 поощряет эту лучшую практику, предоставляя объект Optional.

Ответ 3

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

Ответ 4

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