Collections.reverseOrder如何知道返回Comparator <t> </t>时要使用的类型参数

时间:2012-03-22 18:01:48

标签: java

根据Java API规范,Collections.reverseOrder的签名是

public static <T> Comparator<T> reverseOrder()

方法描述中给出的示例表明它需要用作

Arrays.sort(a, Collections.reverseOrder());

当我们调用该方法时,我们无处指定要使用的类型(T解析为什么)。

在这种情况下,编译器如何解析T?可以根据分配给它的对象的类型来解析返回类型(T)吗?

顺便说一句,我知道重载的reverseOrder(Comparator<T> c)方法。

5 个答案:

答案 0 :(得分:4)

Arrays.sort()知道它需要什么样的Comparator,因为第一个参数(T)指定了a

public static <T> void sort(T[] a, Comparator<? super T> c)

编辑:

@Louis Wasserman正确地指出我们只需要Comparator<? super T>,而不是Comparator<T>。由于Object是任何T的超类,因此Comparator<Object>(如果没有给出通用参数,则为默认值)就足够了。

答案 1 :(得分:2)

T正在解决Object。这是通过,因为Arrays.sort(T[], Comparator<? super T>)会接受Comparator<Object>,因为ObjectT的超类型。

Eclipse确认Collections.reverseOrder()已解析为代码中的Comparator<Object>

String[] array = new String[10];
Arrays.sort(array, Collections.reverseOrder());

答案 2 :(得分:1)

T根据a的类型解析。

答案 3 :(得分:1)

可以推断出方法调用中的类型。

Xyz[] a;
Arrays.sort(a, Collections.reverseOrder());

相当于

Xyz[] a;
Arrays.<Xyz>sort(a, Collections.<Xyz>reverseOrder());

从Java SE 7开始,类似的东西适用于构造函数,只需要使用“钻石'运算符'”(原因不是很充分)。

List<Xyz> xyzs = new ArrayList<>();

答案 4 :(得分:0)

如果查看Arrays.sort()的签名,您会看到您正在调用的签名具有Arrays.sort(T[], Comparator<? super T>)的签名,因此您实际上以数组类型的形式提供了一个类型参数你传了进来。

编辑:我在这里犯了一个小错误,并假设调用reverseOrder()可以infer类型,但没有至少一个参数,没有方法可以实际做到这一点(参见链接) 。

如果对Collections.reverseOrder()的调用采用了参数,那么方法可以从调用中推断出类型。该方法的重载版本采用Comparator<T>作为参数。我们可以用以下内容演示Eclipse中的推理;将鼠标悬停在Collections.reverseOrder()上:


public class CollectionsFun {
   public static void main(String[] args) {
      String[] strs = new String[] {"foo", "bar", "baz"};
      Comparator<String> comp = new Comparator<String>() {
         @Override
         public int compare(String o1, String o2) {
            return o1.compareTo(o2);
         }        
      };
      Arrays.sort(strs, Collections.reverseOrder(comp));
      System.out.println(strs);
   }
}

因为在此示例中对reverseOrder()的调用采用了类型化参数,所以静态方法可以推断出需要返回的类型。但是,当您调用带有 no 参数的方法的重载形式时,不能推断出任何类型,因此返回Comparator<Object>而不是Comparator<String>。您可以通过将鼠标悬停在以下代码中的reverseOrder()来电来查看:


public class CollectionsFun {
   public static void main(String[] args) {
      String[] strs = new String[] {"foo", "bar", "baz"};
      Arrays.sort(strs, Collections.reverseOrder());
      System.out.println(strs);
   }
} 

由于Arrays.sort()的签名表示它需要Comparator<? super T>才能匹配Comparator<Object>。所以这一切都在没有给你任何地方的“原始类型”警告的情况下进行编译。

最后,如果您想要展示如何在没有类型推断的情况下工作,您将执行以下操作:


public class CollectionsFun {
   public static void main(String[] args) {
      String[] strs = new String[] {"foo", "bar", "baz"};
      Arrays.sort(strs, Collections.<String>reverseOrder());
      System.out.println(strs);
   }
}

上面提供的type参数可确保返回的Comparator类型为Comparator<String>