Как использовать Guava Необязательно как «естественно ковариантный объект»

#generics #guava #covariance

#дженерики #guava #ковариация

Вопрос:

Новые необязательные состояния Guava 10 являются естественно ковариантными и, следовательно, могут быть кастомизированы.

Если я попробую, это выглядит немного уродливо:

 Optional<Integer> opti = Optional.of(42);
Optional<Number>  optn =  (Optional) opti;
 

Мне нравится видеть некоторые служебные функции, такие как:

 static <T> Optional<T> transform(Optional<? extends T> opt, Class<T> clazz);
 

(как выразить это как функцию-член Optional ?)

Возможно ли вообще определить объект функции преобразования, например:

 static <T> Function<Optional<? extends T>, Optional<T>> 
transformer(Class<T> class);
 

чтобы преобразовать a Collection<Optional<Double>> в a Collection<Optional<Number>> без создания новых объектов для каждого?

Я думаю, что даже возвращаемый объект функции может быть реализован внутренним синглтоном.

Ответ №1:

Хотя кастинг на самом деле еще уродливее, чем вы думаете:

 Optional<Integer> opti = Optional.of(42);

@SuppressWarnings("unchecked") // safe covariant cast
Optional<Number> optn = (Optional) opti;
 

… мы по-прежнему считаем, что это именно то, что вам следует делать, и исключили предоставление метода, который вы запрашиваете.

Это нормально, что это немного громоздко, потому что вам очень редко нужно делать что-то подобное, если вы правильно используете подстановочные знаки в своих подписях API, как описано в Effective Java .

Ответ №2:

Указав тип of метода, вы можете полностью избежать приведения:

         Optional<Number> optx = Optional.<Number>of(42);
 

Комментарии:

1. Нет необходимости в параметре уродливого типа: Optional.of((Number) 42);