gpt4 book ai didi

java - 为什么 Function.identity() 会破坏类型具体化,而 t -> t 却不会?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:22:17 27 4
gpt4 key购买 nike

Java 8 lambdas, Function.identity() or t->t 找到答案似乎暗示 Function.identity() 几乎总是等同于 t -> t。但是,在下面看到的测试用例中,将 t -> t 替换为 Function.identity() 会导致编译器错误。这是为什么?

public class Testcase {

public static <T, A, R, K, V> Collector<T, A, R> comparatorOrdering(
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper,
Comparator<? super K> keyComparator,
Comparator<? super V> valueComparator) {
return null;
}

public static void main(String[] args) {
Map<Integer, String> case1 = Stream.of(1, 2, 3).
collect(comparatorOrdering(t -> t, t -> String.valueOf(t),
Comparator.naturalOrder(), Comparator.naturalOrder()));
Map<Integer, String> case2 = Stream.of(1, 2, 3).
collect(comparatorOrdering(Function.identity(), t -> String.valueOf(t),
Comparator.naturalOrder(), Comparator.naturalOrder()));
}
}

情况 1 编译正常,但情况 2 失败:

method comparatorOrdering in class Testcase cannot be applied to given types;
collect(comparatorOrdering(Function.identity(), t -> String.valueOf(t),
required: Function<? super T#1,? extends K>,Function<? super T#1,? extends V>,Comparator<? super K>,Comparator<? super V>
found: Function<Object,Object>,(t)->Strin[...]Of(t),Comparator<T#2>,Comparator<T#3>
reason: inferred type does not conform to upper bound(s)
inferred: Object
upper bound(s): Comparable<? super T#4>,T#4,Object
where T#1,A,R,K,V,T#2,T#3,T#4 are type-variables:
T#1 extends Object declared in method <T#1,A,R,K,V>comparatorOrdering(Function<? super T#1,? extends K>,Function<? super T#1,? extends V>,Comparator<? super K>,Comparator<? super V>)
A extends Object declared in method <T#1,A,R,K,V>comparatorOrdering(Function<? super T#1,? extends K>,Function<? super T#1,? extends V>,Comparator<? super K>,Comparator<? super V>)
R extends Object declared in method <T#1,A,R,K,V>comparatorOrdering(Function<? super T#1,? extends K>,Function<? super T#1,? extends V>,Comparator<? super K>,Comparator<? super V>)
K extends Object declared in method <T#1,A,R,K,V>comparatorOrdering(Function<? super T#1,? extends K>,Function<? super T#1,? extends V>,Comparator<? super K>,Comparator<? super V>)
V extends Object declared in method <T#1,A,R,K,V>comparatorOrdering(Function<? super T#1,? extends K>,Function<? super T#1,? extends V>,Comparator<? super K>,Comparator<? super V>)
T#2 extends Comparable<? super T#2>
T#3 extends Comparable<? super T#3>
T#4 extends Comparable<? super T#4> declared in method <T#4>naturalOrder()

我的环境是 Windows 10,64 位,Oracle JDK build 1.8.0_92-b14。

更新:看到这是在 ecj 下编译的,我有一个后续问题:这是 javac 中的错误吗? JLS 对此案有何看法?

最佳答案

Ecj 能够推断出正确的(?)类型参数(整数)来匹配约束。由于某种原因,Javac 得出了不同的结果。

这不是 javac/ecj 第一次在类型参数的推断中表现不同。

在这种情况下,您可以使用 Function. identity() 给 javac 一个提示,使其可以使用 javac 进行编译。

对于Function.identity()和t->t的区别:

  • Function.identity() 是函数
  • t->t 在这种情况下是 Function

所以t->t在匹配的方法上更加灵活。

关于java - 为什么 Function.identity() 会破坏类型具体化,而 t -> t 却不会?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38034982/

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