可选参数不正常[重复]

时间:2022-09-27 11:13:41

This question already has an answer here:

这个问题在这里已有答案:

I may be having it wrong but i am getting an error with an Optional<> as method argument in Java.

我可能错了,但我在Java中使用Optional <>作为方法参数时出错。

I have an interface:

我有一个界面:

public interface FooInterface;

And a class that implements it

还有一个实现它的类

public class Foo implements FooInterface;

Now, suppose i have a method that receives an Optional<FooInterface>

现在,假设我有一个接收Optional 的方法

someMethod(Optional<FooInterface> arg)

I get an error if i do this:

如果我这样做,我会收到错误:

Optional<Foo> foo = Optional.of(new Foo());
someMethod(foo);

It says that Optional<FooInterface> is expected instead of Optional<Foo>.

它说可选 而不是Optional

Why is that?

这是为什么?

3 个解决方案

#1


1  

  1. Use the interface type FooInterface:

    使用接口类型FooInterface:

    final FooInterface foo = new Foo();
    final Optional<FooInterface> optional = Optional.of(foo);
    
  2. Correct the argument type to Optional<? extends FooInterface>. It'll allow passing an Optional<AnyFooInterfaceSubclass>.

    将参数类型更正为Optional 。它将允许传递Optional

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

    请勿尝试使用Optional参数和字段。

#2


1  

That is a general drawback of generic types involving extends/implements.

这是涉及扩展/实现的泛型类型的一般缺点。

interface Ifc { }
class Cls implements Ifc { }
void somemethod2(List<Ifc> arg) { }

List<Cls> list = new UnlinkedList<>();
somemethod2(list); // COMPILE ERROR

In your case a solution would be:

在您的情况下,解决方案将是:

somemethod(Optional<FooInterface>.of(foo));

Or declare

void someMethod(Optional<? extends FooInterface> arg) {

Fortunately Optional is immutable, but for List this would be problematically, as you could not set an element with Foo, as it could have been a List of an other FooInterface implementing class. So maybe better to avoid.

幸运的是,Optional是不可变的,但是对于List,这将是有问题的,因为你不能用Foo设置一个元素,因为它可能是另一个FooInterface实现类的List。所以最好避免。


There exist some proponents of avoiding Optional parameters, in favor of doing only work on non-optional objects. I do not see that as such. IMHO there are many valid uses of Optional parameters.

存在一些避免可选参数的支持者,支持仅对非可选对象进行操作。我不这么认为。恕我直言,可选参数有许多有效用途。

#3


0  

This has nothing to do with Optional itself, it applies to any generic type.

这与Optional本身无关,它适用于任何泛型类型。

Java generics are invariant, which means Collection<Foo> (or Optional, or whatever) is not a subtype of Collection<FooInterface>, even though Foo itself is a subtype of FooInterface.

Java泛型是不变的,这意味着Collection (或Optional,或其他)不是Collection 的子类型,即使Foo本身是FooInterface的子类型。

You need to make that generic type covariant using a wildcard (as @Henrik pointed out already):

您需要使用通配符来创建该泛型类型协变(如@Henrik已经指出的那样):

/**
 * accepts an optional value of type `FooInterface` or any subtype
 */
someMethod(Optional<? extends FooInterface> arg);    

#1


1  

  1. Use the interface type FooInterface:

    使用接口类型FooInterface:

    final FooInterface foo = new Foo();
    final Optional<FooInterface> optional = Optional.of(foo);
    
  2. Correct the argument type to Optional<? extends FooInterface>. It'll allow passing an Optional<AnyFooInterfaceSubclass>.

    将参数类型更正为Optional 。它将允许传递Optional

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

    请勿尝试使用Optional参数和字段。

#2


1  

That is a general drawback of generic types involving extends/implements.

这是涉及扩展/实现的泛型类型的一般缺点。

interface Ifc { }
class Cls implements Ifc { }
void somemethod2(List<Ifc> arg) { }

List<Cls> list = new UnlinkedList<>();
somemethod2(list); // COMPILE ERROR

In your case a solution would be:

在您的情况下,解决方案将是:

somemethod(Optional<FooInterface>.of(foo));

Or declare

void someMethod(Optional<? extends FooInterface> arg) {

Fortunately Optional is immutable, but for List this would be problematically, as you could not set an element with Foo, as it could have been a List of an other FooInterface implementing class. So maybe better to avoid.

幸运的是,Optional是不可变的,但是对于List,这将是有问题的,因为你不能用Foo设置一个元素,因为它可能是另一个FooInterface实现类的List。所以最好避免。


There exist some proponents of avoiding Optional parameters, in favor of doing only work on non-optional objects. I do not see that as such. IMHO there are many valid uses of Optional parameters.

存在一些避免可选参数的支持者,支持仅对非可选对象进行操作。我不这么认为。恕我直言,可选参数有许多有效用途。

#3


0  

This has nothing to do with Optional itself, it applies to any generic type.

这与Optional本身无关,它适用于任何泛型类型。

Java generics are invariant, which means Collection<Foo> (or Optional, or whatever) is not a subtype of Collection<FooInterface>, even though Foo itself is a subtype of FooInterface.

Java泛型是不变的,这意味着Collection (或Optional,或其他)不是Collection 的子类型,即使Foo本身是FooInterface的子类型。

You need to make that generic type covariant using a wildcard (as @Henrik pointed out already):

您需要使用通配符来创建该泛型类型协变(如@Henrik已经指出的那样):

/**
 * accepts an optional value of type `FooInterface` or any subtype
 */
someMethod(Optional<? extends FooInterface> arg);