为什么Java允许比较(字符串,字符串)比较器方法采用对象类型的参数?



这是我的代码:

public class Demo {
public static final Comparator<String> SORT_BY_LENGTH = new SortByLength();
private static class SortByLength implements Comparator<String>{
public int compare(String w, String v) {
return w.length()-v.length();
}
}
public static void main(String[] args) {
Object o1 = "abc", o2 = "bc";
Comparator c = SORT_BY_LENGTH;
System.out.println(c.compare(o1, o2));//OK, output 1
}
}

所以让我感到困惑的是 compare() 方法的签名将 2 个字符串变量作为参数。但是,即使我输入 Object 类型的 2 个参数,它仍然有效。为什么?

PS:如果我定义一些普通的方法如下,那么编译器会抱怨有错误,因为 Object 无法转换为 String。

public static int foo(String w, String v) {
return w.length()-v.length();
}
public static void main(String[] args) {
Object o1 = "abc", o2 = "bc";
System.out.println(foo(o1, o2));// compiling error!
}

您可以在此处使用Object作为参数,因为您使用了原始类型的Comparator,这是您通常不应该做的事情。

这是你做的地方:

Comparator c = SORT_BY_LENGTH;

看看没有通用参数可以Comparator?这是使用原始类型的标志。可以将参数化类型的任何实例(如SORT_BY_LENGTH)分配给原始类型。但是,由于原始类型Comparator没有泛型参数,因此其compare方法需要两个Object而不是Strings。所以理论上你可以把任何东西传递到compare.

但是,如果方法中输入了错误类型的对象,则会引发异常。试着把两个new Object()放进去!

这就是不应将参数化类型分配给原始类型的原因。它们不是类型安全的。你应该做这样的事情:

Comparator<String> c = SORT_BY_LENGTH;

或直接使用SORT_BY_LENGTH

如果进行了上述更改,则对compare的调用将不再编译,因为它需要String。应将o1o2的类型更改为String

最新更新