给定`T`和`U`,其中`T延伸U`如何返回'U`

Sco*_*bie 8 java generics optional

给定一个API:

class Bar { ... }
class Foo extends Bar { ... }
Run Code Online (Sandbox Code Playgroud)

在Java的Optional类型中,我们可以说:

Optional<Foo> fooOption = ...
fooOption.orElse(aFoo) // returns something of type Foo
Run Code Online (Sandbox Code Playgroud)

但是,既然Foo是a Bar,我想能够说:

Optional<Foo> fooOption = ...
fooOption.orElse(aBar) // returns something of type Bar
Run Code Online (Sandbox Code Playgroud)

作为练习,我想用另一种类型完成此操作:

public abstract class Option<T> {
    // this doesn't compile
    public abstract <U super T> U orElse(U other);
}
Run Code Online (Sandbox Code Playgroud)

我如何重写这个以进行编译,还支持在需要时同时扩展类型的能力?

vsm*_*kov 6

但是,既然Foo是一个Bar

Bar不是Foo.我的意思是你可以这样做:

Optional<Bar> fooOpt = Optional.of(new Foo());
Bar bar = fooOpt.orElse(new Bar());
Run Code Online (Sandbox Code Playgroud)

但你不能做同样的事情,Optional<Foo>因为它违反了Optional.orElse方法的类型约束.

在假设的实现中,Option<T>您应该明确定义U为超类型T

public class Option<U, T extends U> {
    T value;

    public U orElse(U other) {
        if (value != null) {
            return value;
        }
        return other;
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您可以编写这样的代码

Option<Foo, Bar> fooOpt = Option.of(new Foo());
Bar bar = fooOpt.orElse(new Bar());
Run Code Online (Sandbox Code Playgroud)