可选参数不正常

时间:2018-01-04 15:05:02

标签: java optional

我可能错了,但我在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>

为什么?

3 个答案:

答案 0 :(得分:1)

  1. 使用接口类型FooInterface

    final FooInterface foo = new Foo();
    final Optional<FooInterface> optional = Optional.of(foo);
    
  2. 将参数类型更正为Optional<? extends FooInterface>。它允许传递Optional<AnyFooInterfaceSubclass>

  3. Try not using the Optional for parameters and fields.

答案 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