根据Java API规范,Collections.reverseOrder的签名是
public static <T> Comparator<T> reverseOrder()
方法描述中给出的示例表明它需要用作
Arrays.sort(a, Collections.reverseOrder());
当我们调用该方法时,我们无处指定要使用的类型(T解析为什么)。
在这种情况下,编译器如何解析T?可以根据分配给它的对象的类型来解析返回类型(T)吗?
顺便说一句,我知道重载的reverseOrder(Comparator<T> c)
方法。
答案 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>
,因为Object
是T
的超类型。
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>
。