gpt4 book ai didi

java - 如何向上转换 Java 8 Optional 中包含的对象?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:06:48 25 4
gpt4 key购买 nike

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

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.) 给出错误。我可以通过创建另一个函数来解决它。

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

最佳答案

我会写一个这样的方法:

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

(如果你不喜欢这个名字 copyOf,请看我下面关于 Guava 的 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具有以下属性:保证不会因 setter 方法采用依赖于类型变量 T 的参数而导致任何状态更改.呸。相当一口。我会让它更具体。

因为 Optional

  1. 没有 setter 方法(任何类型的,但更普遍的是没有采用 TSomeGenericType<T> 等类型参数的方法)
  2. final (所以你不能将它子类化来添加一个 setter 来违反前一点)

对于 Optional<T> 所持有的值,您无能为力。 (或缺少)这将使它不是 T 的实例(或缺乏)。

而且因为 T 的每个实例也是它的父类(super class)的一个实例,没有什么不安全的:

SuperclassOfT s = optionalOfT.get();

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

您会在 Guava's ImmutableList.copyOf 中找到类似的代码(上面将其称为“copyOf”的灵感,尽管它并不是真正的副本)。那里有 setter 方法(如 add ),但这些方法会立即抛出 UnsupportedOperationException s,因此不会影响列表的状态。


请注意,虽然不可变类型具有上述必要属性以确保此类转换安全,但该类型不一定需要不可变才能安全地执行转换。

例如,您可以有一个 ErasableOptional<T>类型,它有一个 erase()其上的方法,在调用时将“存在”值转换为“不存在”值(即 get() 不再成功)。将这样的实例转换为 ErasableOptional<SupertypeOfT> 是安全的因为该值是 T或缺席;你不能让它不是 SupertypeOfT 的实例或缺席。

关于java - 如何向上转换 Java 8 Optional 中包含的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44852936/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com