gpt4 book ai didi

Java 类型变体,泛型类型的消费者

转载 作者:搜寻专家 更新时间:2023-10-30 23:02:31 26 4
gpt4 key购买 nike

我正在努力理解变体在 Java 中的工作原理。

在下面的例子中,我定义了一个函数test这需要 Consumer .该函数是在没有逆变的情况下定义的,所以我希望 Consumer<Object>不是 Consumer<Pair<Animal, Animal>> 的子类型.然而,代码编译,测试接受 lambda Variance:::superAction .

我错过了什么?

import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;

import java.util.function.Consumer;

public class Variance {

public static void main(String[] args) {
test(Variance::exactMatchAction);
test(Variance::superAction);
}

private static void exactMatchAction(Pair<Animal, Animal> pair) {
System.out.println(pair.getLeft().getClass().getName());
}

private static void superAction(Object obj) {
System.out.println(obj.getClass().getName());
}

private static void test(Consumer<Pair<Animal, Animal>> action) {
action.accept(ImmutablePair.of(new Animal(), new Animal()));
action.accept(ImmutablePair.of(new Dog(), new Dog()));
}

static class Animal { }

static class Dog extends Animal { }
}

编辑:根据@Thielo 的评论,引用 superAction被脱糖为 Consumer<Pair<Animal, Animal>>不是 Consumer<Object> .

给出 test 的正确类型方法类似于:

void test(Consumer<? super Pair<? extends Animal, ? extends Animal>>)

此类型将允许我们传递 Consumer<Object>test ,并且还允许我们使用 Pair<Dog, Dog> 等参数调用消费者而不仅仅是 Pair<Animal, Animal> .

作为后续问题,使用此更新类型进行测试,它不会接受像 void exactMatchAction<Pair<Animal, Animal>> 这样的方法引用不再,只有void exactMatchAction<Pair<? extends Animal, ? extends Animal>> .这是为什么?

最佳答案

方法引用表达式(例如您的 Variance::superAction )是多边形表达式 (JLS8, 15.13)。多边形表达式的类型可能受表达式的目标类型 (JLS8, 15.3) 的影响,这是该上下文中预期的类型 (JLS8, 5),即 Consumer<Pair<Animal, Animal>> ,在你的情况下。

详细信息在 JLS8, 15.13.2 中有详细说明。基本思想是对功能接口(interface)类型进行特殊处理,例如 Consumer .具体来说,方法类型只需要与函数类型一致(即 Pair<Animal, Animal> -> void——注意 Consumer 已从此处的类型考虑中消失),这由“identif[ying ] 对应于引用的单个编译时声明”(并具有 void 作为返回类型)。在这里,“识别”声明的概念可以追溯到 15.12.2,基本上描述了方法重载解析过程。换句话说,该语言现在采用 Consumer<Pair<Animal, Animal>>.accept() 预期的函数参数。 (即 Pair<Animal, Animal> )并检查是否可以用它调用方法引用(这解决了在有多个同名静态方法的情况下的重载)。

关于Java 类型变体,泛型类型的消费者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32429389/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com