为什么以下代码会自动装箱为错误的类型并进行编译?
Why does the following code autoboxes to wrong types and compiles?
class Test {
public static <T> boolean test(T a, T b) {
return a.equals(b);
}
public static void main(String[] args) {
int i = 0;
long j = 0;
if (!test(i, j)) {
throw new RuntimeException("i is not equal to j");
}
}
}
在上面的代码片段中,我预计会发生以下两种情况之一:
会出现编译错误,因为i
被自动装箱为Integer
而j
被自动装箱为Long
并且声明方法 test
要求它的两个参数属于同一类型。
i
和 j
都被自动装箱为 Long 和要编译的代码,运行 显示 i
和 j
相等。
但实际上发生的是 i
被自动装箱为 Integer
并且 j
被自动装箱为 Long
并且代码编译没有错误。这不和test
的声明相矛盾吗?允许这样的代码的原因是什么?
如果 i
被装箱到 Integer
并且 j
被装箱到 Long
,调用方法 test
仍然是合法的通用类型假定为 java.lang.Number
,它是 Integer
和 Long
.
的超类型
其实你可以用任何两个对象调用你的test
方法,因为T
可以作为基类型Object
.方法上的泛型根本不限制其参数。
class Test {
public static <T> boolean test(T a, T b) {
return a.equals(b);
}
public static void main(String[] args) {
int i = 0;
long j = 0;
if (!test(i, j)) {
throw new RuntimeException("i is not equal to j");
}
}
}
在上面的代码片段中,我预计会发生以下两种情况之一:
会出现编译错误,因为
i
被自动装箱为Integer
而j
被自动装箱为Long
并且声明方法test
要求它的两个参数属于同一类型。i
和j
都被自动装箱为 Long 和要编译的代码,运行 显示i
和j
相等。
但实际上发生的是 i
被自动装箱为 Integer
并且 j
被自动装箱为 Long
并且代码编译没有错误。这不和test
的声明相矛盾吗?允许这样的代码的原因是什么?
如果 i
被装箱到 Integer
并且 j
被装箱到 Long
,调用方法 test
仍然是合法的通用类型假定为 java.lang.Number
,它是 Integer
和 Long
.
其实你可以用任何两个对象调用你的test
方法,因为T
可以作为基类型Object
.方法上的泛型根本不限制其参数。