如何使用Guava Optional作为"自然协变对象"

Dit*_*itz 4 generics covariance guava

新的番石榴10 可选状态是自然协变的,因此可以被铸造.

如果我这样做,它看起来有点难看:

Optional<Integer> opti = Optional.of(42);
Optional<Number>  optn =  (Optional) opti;
Run Code Online (Sandbox Code Playgroud)

我喜欢看到一些实用功能:

static <T> Optional<T> transform(Optional<? extends T> opt, Class<T> clazz);
Run Code Online (Sandbox Code Playgroud)

(如何将其表示为Optional的成员函数?)

甚至可以定义转换函数对象,如:

static <T> Function<Optional<? extends T>, Optional<T>> 
transformer(Class<T> class);
Run Code Online (Sandbox Code Playgroud)

为了将a变换Collection<Optional<Double>>为a Collection<Optional<Number>>而不为每个创建新对象?

我认为即使返回的Function对象也可以通过内部单例来实现.

Kev*_*ion 8

尽管施法实际上比你想象的还要丑陋:

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

@SuppressWarnings("unchecked") // safe covariant cast
Optional<Number> optn = (Optional) opti;
Run Code Online (Sandbox Code Playgroud)

......我们仍然认为这正是你应该做的,并且排除了提供你所要求的方法.

没关系,这有点麻烦,因为你应该很少需要这样做,只要你在API签名中正确使用通配符,如Effective Java所述.


Dre*_*rew 8

通过指定of方法的类型,您可以完全避免强制转换:

        Optional<Number> optx = Optional.<Number>of(42);
Run Code Online (Sandbox Code Playgroud)