Java 为什么Function.identity()会破坏类型具体化,但t->;t不是吗?

Java 为什么Function.identity()会破坏类型具体化,但t->;t不是吗?,java,generics,reification,Java,Generics,Reification,在中找到的答案似乎暗示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

在中找到的答案似乎暗示
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()));
    }
}
公共类测试用例{
公共静态收集器比较器排序(

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

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

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

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

  • Function.identity()是一个函数

  • 在这种情况下,t->t是Function,
    i->i
    Function.identity()
    之间的区别在以下情况下非常明显:(1)收集器是嵌套的,(2)在嵌套的深层某处需要向上投射

    示例:假设我们要按元素类将
    列表中的元素分类到具有特定列表的映射中。(除了值为
    列表
    ,它类似于,因此类似于假设的
    类到安装多映射
    )下游收集器
    toList()
    通常将值收集到
    列表中
    。但是,如果映射的值类型是通配符类型
    列表
    ,则类型推断不能简单地与之匹配。解决方案是使收集器适应,使其假装收集
    列表
    ,这是通过中间
    收集然后
    收集器完成的


    现在的问题是,finisher函数应该是什么样子?Lambda
    i->i
    的行为类似于
    函数。你能分享一些关于你的env的详细信息吗?这在我的上编译得很好。我可以用Java 1.8.092(OpenJDK)重现这一点@StephenC哪个版本是1.8.0_92?我使用的是1.8.0_92-b14,无法复制。
    $java-version
    ==>
    openjdk版本“1.8.0_92”openjdk运行时环境(构建1.8.0_92-b14)openjdk 64位服务器虚拟机(构建25.92-b14,混合模式)
    …在Fedora Linux上,错误可以在javac中重现,而不是在ecj中重现,因此eclipse中的错误不会说明太多。在指定IntegerI类型后,它可以使用
    javac 1.8.0\u 60进行编译。我添加了一个后续问题。我知道您试图提供帮助,但您的答案实际上并没有回答这个问题。我知道
    I->I
    很好aving与
    Function.identity()
    不同,但您凭什么相信它应该这样做?JLS是否规定
    i->i
    应该允许上传?请参考。
    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()