В Java Optional
реализуется как public final class Optional<T> { ... }
, а не как запечатанная иерархия Some
и None
.
Почему здесь не так? Это обходное решение для отсутствия sealed
в Java? Есть ли какие-то более глубокие рассуждения?
Если вы посмотрите на реализацию метода, вы увидите, что, пройдя этот случай, он имеет уродливые нулевые проверки:
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}
Они не только уродливы, но если у вас более длинная цепочка методов, isPresent
нужно будет оценивать во время каждого вызова, даже если Optional
пуст с самого начала.
Если бы мы могли передать фиксированную реализацию по цепочке, ее можно было бы избежать.
optional
.map(i -> i) // isPresent()
.map(Object::toString) // isPresent()
.map(String::length) // isPresent()
.map(...) // isPresent()
Вопрос
Почему не были подтипы, используемые для моделирования пустых и непустых случаев?
Я не спрашиваю конкретно, почему Optional
является окончательным, а почему он не был реализован с Some
и None
, как это делают многие другие языки, поэтому Почему необязательно объявлено как окончательный класс, не очень полезно.