本文介绍了为什么Function.identity()中断类型实例,但是t - > t不?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在上发现的答案似乎意味着 Function.identity()几乎总是等于 t - >吨。但是,在下面看到的测试用例中,替换 t - > t Function.identity()导致编译器错误。为什么会这样?

  public class Testcase {

public static< T,A,R, K,V>收集器< T,A,R> compareOrdering(
函数< ;? super T,?extends K> keyMapper,
函数< ;? super T,?extends V> valueMapper,
Comparator< ;? super K> keyComparator,
比较器< ;? 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()));






$ b

情况1编译得很好,但情况2失败:

 方法compareOrdering在类Testcase中不能应用于给定的类型; 
collect(函数<?super T#1,?extends K>,Function< super T# (t),(t),>函数<对象,对象> ;,(t) - >比较器< T#2>,比较器< T#3>
reason:推断的类型不符合上限
推断:对象
上限(s):可比较< T#4,T#4,对象
其中T#1,A,R,K,V,T#2,T#3,T#4是类型变量:
T# 1扩展了在方法< T#1,A,R,K,V> comparatorOrdering(Function< super T#1,?extends K> ;, Function< super T#1,?extends V> < super K>,Comparator<?super V>)
A extends在方法< T#1,A,R,K,V> comparatorOrdering中声明的对象(Function< super T#1,?extends K& ,函数<超级T#1,?扩展V> ;,比较器<超级K>比较器< ;? super>)
R extends在方法< T#1,A,R,K,V> comparatorOrdering(Function< super T#1,?extends K> ;, Function< super T#1 ,< V extends V>,Comparator< Super K>,Comparator< V super V>)
K extends在方法< T#1,A,R,K,V> comparatorOrdering(Function< super T#1,?扩展K>,函数<超级T#1,?扩展V>,比较器<超级K>,比较器"超级V>)
V扩展在方法< 1,A,R,K,V> comparatorOrdering(函数<超级T#1,?扩展K>,函数<超级T#1,?扩展V> ;,比较<超级K> ;)
T#2扩展了Comparable< ;?超级T#2>
T#3延伸可比较< ;?超级T#3>
T#4延伸Comparable< ;?超级T#4>声明在方法< T#4> naturalOrder()中

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


$ b 更新:看到这个在ecj下编译,我有一个后续问题:Is这是 javac 中的错误?对于这种情况,JLS有什么看法?

解决方案

Ecj能够引用正确的(?)类型参数(Integer )来匹配约束条件。由于某种原因,Javac产生了不同的结果。


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


$

在这种情况下,您可以使用Function为< Integer> identity()提供一个提示,使它可以用javac编译。

在Function.identity()和t-> t之间:


  • Function.identity()是Function< T,T>
  • 在这种情况下
    t-> t是函数<超整型,?扩展整数>


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

Answers found at Java 8 lambdas, Function.identity() or t->t seem to imply that Function.identity() is almost always equivalent to t -> t. However, in the testcase seen below, replacing t -> t by Function.identity() results in a compiler error. Why is that?

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()));
    }
}

Case 1 compiles just fine but case 2 fails with:

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()

My environment is Windows 10, 64-bit, Oracle JDK build 1.8.0_92-b14.

UPDATE: Seeing as this compiles under ecj, I have a follow-up question: Is this a bug in javac? What does the JLS have to say about this case?

解决方案

Ecj is able to infere the correct(?) type argument (Integer) to match the constraints. Javac for some reason comes to a different result.

Thats not the first time javac/ecj behave differently in inference of type parameters.

In that case you can give javac a hint with Function.<Integer>identity() to make it compileable with javac.

For the difference between Function.identity() and t->t:

  • Function.identity() is Function<T,T>
  • t->t in that case is Function<? super Integer, ? extends Integer>

So t->t is more flexible in the methods it can match to.

这篇关于为什么Function.identity()中断类型实例,但是t - &gt; t不?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 05:19