java - 捕获#1-of ? super C 解释为通用接口(interface)中的 C

标签 java generics java-8 functional-programming bounded-wildcard

给定以下类(class):

class A { public A a() {return new A();}; };
class B extends A { public B b() {return new B();} };
class C extends B { public C c() {return new C();} };
class D extends C { public D d() {return new D();} };

我想写一些UnaryOperator可以接受 A、B 和 C 的实例,但不能接受 D。

所以我选择声明引用类型是 UnaryOperator<? super C> 。因为我正在使用 super ,这意味着它也可以接受 Object 的实例.

UnaryOperator<? super C> op1 = arg -> arg.a(); // does not compile, arg could be Object
UnaryOperator<? super C> op2 = arg -> arg.b(); // does not compile, arg could be Object
UnaryOperator<? super C> op3 = arg -> arg.c(); // does compile
UnaryOperator<? super C> op4 = arg -> arg.d(); // this is not expected to compile

为什么op1使代码无法编译并显示一条消息

Type mismatch: cannot convert from A to C

op2使代码无法编译并显示一条消息

Type mismatch: cannot convert from B to C ,

但是op3编译正常,让我调用一个仅在 C 中可用的方法?

最佳答案

Why does op1 makes the code fail to compile...?

当通用函数接口(interface)通过通配符参数化时,有不同的实例化可以满足通配符并产生不同的函数类型。例如,每个 1:

UnaryOperator<C> (function type C -> C);
UnaryOperator<B> (function type B -> B);
UnaryOperator<A> (function type A -> A);
UnaryOperator<Object> (function type Object -> Object);

UnaryOperator<? super C> .

有时,可以从上下文中获知,例如 lambda 的参数类型,以及预期的函数类型。其他时候,需要选择一个:

UnaryOperator<? super C> op1 = (A arg) -> arg.a();
                                ^

UnaryOperator<? super C> op2 = (B arg) -> arg.b();
                                ^
...

如果您不选择一个,则使用边界2:

UnaryOperator<? super C> op = arg -> arg.c(); // valid

哪里C是一个界限,所以 lambda 表达式是 UnaryOperator<C>在这种情况下。


1 - JLS 9.9. Function Types - 最后一段。
2 - JLS 15.27.3. Type of a Lambda Expression - 如果T是通配符参数化函数接口(interface)类型并且 lambda 表达式是隐式类型的,则基本目标类型是非通配符参数化 T .

关于java - 捕获#1-of ? super C 解释为通用接口(interface)中的 C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51410687/

相关文章:

java - 验证 vaadin 组合框自定义输入(仅限整数)

Java math.pow 方法,我打印不正确吗? (Java 新手)

swift - NSManagedObject.entity() - 未初始化

datetime - 在 java 8 中解析时间字符串 - ClockHourOfAmPm 的值无效

java - 使用 List 流式传输 anyMatch

java - 将文本区域保存到文件

java - socket接收数据时Java Socket中是否有事件?

c# - 创建其构造函数需要参数的泛型类型的实例?

c# - 字典 - 使用类型作为键并将其限制为仅适用于某些类型

java - 有效地迭代 2 个具有相同对象类型的不同列表(Java8)