我可能错了,但我在Java中使用Optional<>
作为方法参数时出错。
我有一个界面:
public interface FooInterface;
一个实现它的类
public class Foo implements FooInterface;
现在,假设我有一个接收Optional<FooInterface>
someMethod(Optional<FooInterface> arg)
如果我这样做,我会收到错误:
Optional<Foo> foo = Optional.of(new Foo());
someMethod(foo);
它表示Optional<FooInterface>
代替Optional<Foo>
。
为什么?
答案 0 :(得分:1)
使用接口类型FooInterface
:
final FooInterface foo = new Foo();
final Optional<FooInterface> optional = Optional.of(foo);
将参数类型更正为Optional<? extends FooInterface>
。它允许传递Optional<AnyFooInterfaceSubclass>
。
答案 1 :(得分:1)
这是涉及extends/implements
的泛型类型的一般缺点。
interface Ifc { }
class Cls implements Ifc { }
void somemethod2(List<Ifc> arg) { }
List<Cls> list = new UnlinkedList<>();
somemethod2(list); // COMPILE ERROR
在您的情况下,解决方案将是:
somemethod(Optional<FooInterface>.of(foo));
或宣布
void someMethod(Optional<? extends FooInterface> arg) {
幸运的是,Optional是不可变的,但是对于List来说这会有问题,因为你不能用Foo设置一个元素,因为它可能是其他FooInterface实现类的List。所以最好避免。
存在一些避免可选参数的支持者,支持仅对非可选对象进行操作。我不这么认为。恕我直言,可选参数有许多有效用途。
答案 2 :(得分:0)
这与Optional
本身无关,它适用于任何泛型类型。
Java泛型是不变的,这意味着Collection<Foo>
(或Optional
或其他)不是Collection<FooInterface>
的子类型,即使Foo
本身是{的子类型{1}}。
您需要使用通配符来创建该泛型类型协变(正如@Henrik已经指出的那样):
FooInterface