#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);