为什么 Java 允许 compare(String, String) Comparator 方法接受 Object 类型的参数?
Why does Java allow a compare(String, String) Comparator method to take arguments of Object type?
所以这是我的代码:
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 个字符串变量作为参数。但是,即使我输入 2 个 Object 类型的参数,它仍然有效。这是为什么?
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
而不是 String
。所以理论上你可以将任何东西传递给 compare
.
但是,如果错误类型的对象进入该方法,将抛出异常。试试把两个 new Object()
放在那里!
这就是为什么您不应将参数化类型分配给原始类型。它们不是类型安全的。你应该做这样的事情:
Comparator<String> c = SORT_BY_LENGTH;
或直接使用SORT_BY_LENGTH
。
如果您进行了上述更改,对 compare
的调用将不再编译,因为它需要 String
s。您应该将 o1
和 o2
的类型更改为 String
.
所以这是我的代码:
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 个字符串变量作为参数。但是,即使我输入 2 个 Object 类型的参数,它仍然有效。这是为什么?
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
而不是 String
。所以理论上你可以将任何东西传递给 compare
.
但是,如果错误类型的对象进入该方法,将抛出异常。试试把两个 new Object()
放在那里!
这就是为什么您不应将参数化类型分配给原始类型。它们不是类型安全的。你应该做这样的事情:
Comparator<String> c = SORT_BY_LENGTH;
或直接使用SORT_BY_LENGTH
。
如果您进行了上述更改,对 compare
的调用将不再编译,因为它需要 String
s。您应该将 o1
和 o2
的类型更改为 String
.