我会写一个像这样的方法:
@SuppressWarnings("unchecked") // Safe. See below.static <T> Optional<T> copyOf(Optional<? extends T> opt) { return (Optional<T>) opt;}(如果您不喜欢这个名字
copyOf,请在
ImmutableList下面查看我对番石榴的评论)
就运行速度而言,这是非常有效的:强制转换在编译时被忽略:
static <T> java.util.Optional<T> copyOf(java.util.Optional<? extends T>); Code: 0: aload_0 # Read the parameter. 1: areturn # Return the parameter.
因此,唯一的成本就是方法调用的成本。JIT可以轻松解决此问题。
然后可以像这样调用:
Optional<A> a = copyOf(func2());
这是安全的,因为
Optional具有以下属性:保证不会因使用依赖于type变量的参数的setter方法引起任何状态更改
T。ew
满口。我会更具体一些。
因为
Optional
- 没有setter方法(任何种类的,但更一般的是没有采取类型的参数
T
,SomeGenericType<T>
等) - 是
final
(因此您不能将其子类化以添加违反前一点的二传手)
您无法对
Optional<T>(或缺乏)持有的价值做任何事情,使其 不会 成为
T(或缺乏)的实例。
而且由于的每个实例
T也是其超类的实例,因此没有什么不安全的:
SuperclassOfT s = optionalOfT.get();
因此,此方法是类型安全的(如果您在不存在的可选对象上调用它,它将失败;但这不是类型错误)。
您将在Guava的
ImmutableList.copyOf代码中找到类似的代码(上面的代码称为“
copyOf” 的灵感,即使它并不是真正的副本)。在那里,那里 有
setter方法(像
add),但这些方法马上抛出
UnsupportedOperationException秒,因此不会影响到列表的状态。
请注意,尽管不可变类型具有上述必需的属性才能使这种类型转换安全,但是,为了安全地执行类型转换,该类型不一定必须是不可变的。
例如,您可能有一个
ErasableOptional<T>类型,上面有一个
erase()方法,该方法在被调用时将“当前”值转换为“不存在”值(即
get()不再成功)。将这样的实例强制转换为an是安全的,
ErasableOptional<SupertypeOfT>因为该值要么为a,
T要么不存在;您不能使其
不 成为实例
SupertypeOfT或不存在。



