如何上载Java 8 Optional中包含的对象? [英] How to upcast object contained in Java 8 Optional?

查看:89
本文介绍了如何上载Java 8 Optional中包含的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用Optional对象时,是否有一种有效的方法来进行向上转换. 这是示例代码:

Is there an efficient way to perform upcasting while using an Optional object. Here is a sample code:

class A{}
class B extends A{}

B func(){
    //do something
    return new B();
}

Optional<B> func2(){
    //do something
    return Optional.of(new B());
}

main() {
    A a = func(); // Upcasting works fine
    B b = func(); // Upcasting works fine
    Optional<B> b = func2(); // 1. Works fine
    Optional<A> a = func2(); // 2. How to make this work ?
}

(2.)给出错误.我可以通过创建另一个函数来解决它.

(2.) gives an error. I can solve it by creating another function.

但是有没有一种有效的方法,所以func2()可以用于(1.)和(2.)吗?

But is there an efficient way, so that func2() can be used for both (1.) and (2.) ?

推荐答案

我会写一个像这样的方法:

I would write a method like this:

@SuppressWarnings("unchecked")  // Safe. See below.
static <T> Optional<T> copyOf(Optional<? extends T> opt) {
  return (Optional<T>) opt;
}

(如果您不喜欢名字copyOf,请在下面查看我对番石榴ImmutableList的评论)

(If you don't like the name copyOf, see my comment about Guava's ImmutableList below)

这在运行时速度方面非常有效:强制转换在编译时被忽略:

This is very efficient in terms of runtime speed: the cast gets elided at compile time:

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可以轻松解决此问题.

so the only cost is that of a method call; this is easily done away with by the JIT.

然后您可以像这样调用:

You can then invoke like:

Optional<A> a = copyOf(func2());


这是安全的,因为Optional具有以下属性:保证不会因使用依赖于类型变量T的参数的setter方法导致任何状态更改. ew满口.我会更具体一点.


This is safe because Optional has the following property: it is guaranteed not to have any state changes caused by setter methods taking parameters dependent upon the type variable T. Phew. Quite a mouthful. I'll make it more concrete.

因为Optional

  1. 没有设置方法(任何类型,但更普遍的是没有采用TSomeGenericType<T>等类型的参数)
  2. final(因此您不能将其子类化以添加违反前一点的二传手)
  1. has no setter methods (of any kind, but more generally none that take parameters of type T, SomeGenericType<T> etc)
  2. is final (so you can't subclass it to add a setter to violate the previous point)

对于Optional<T>所拥有的值(或缺少它),您无能为力,这将使其成为T实例(或缺乏)的一个实例.

there is nothing you can do to the value held by the Optional<T> (or lack thereof) that will make it not an instance of T (or lack thereof).

并且由于T的每个实例也是其超类的实例,因此没有什么不安全的:

And because every instance of T is also an instance of its superclasses, there is nothing unsafe about:

SuperclassOfT s = optionalOfT.get();

因此,此方法是类型安全的(如果您在不存在的可选对象上调用它,它将失败;但这不是类型错误).

As such, this method is type safe (it will fail if you've invoked it on a non-present optional; but that's not a type error).

您会在番石榴的ImmutableList.copyOf (上面的称呼为"copyOf"的灵感,即使它并不是真正的副本).那里有 设置方法(如add),但是这些方法会立即抛出UnsupportedOperationException,因此不会影响列表的状态.

You will find similar code in Guava's ImmutableList.copyOf (the inspiration for calling it "copyOf" above, even though it's not really a copy). There, there are setter methods (like add), but those methods immediately throw UnsupportedOperationExceptions, and thus do not affect the list's state.

请注意,尽管不可变类型具有上述必需的属性才能使此类强制转换安全,但不一定必须将类型保持不变才能安全地执行强制转换.

Note that whilst immutable types have the necessary properties described above to make such a cast safe, the type does not necessarily need to be immutable to perform the cast safely.

例如,您可能具有ErasableOptional<T>类型,该类型上具有erase()方法,该方法在被调用时将当前"值转换为缺少"值(即get()不再成功) .将这样的实例强制转换为ErasableOptional<SupertypeOfT>是安全的,因为该值要么是T,要么是不存在.您不能使其 not SupertypeOfT的实例或不存在.

For example, you could have an ErasableOptional<T> type, which has an erase() method on it which, when called, converted a "present" value into an "absent" value (i.e. get() no longer succeeds). It would be safe to cast such an instance to an ErasableOptional<SupertypeOfT> because the value is either a T or absent; you can't make it not an instance of SupertypeOfT or absent.

这篇关于如何上载Java 8 Optional中包含的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆