英文:
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");
}
}
}
在上面的代码片段中,我期望以下两种情况之一发生:
1)会有编译错误,因为 i
被自动装箱为 Integer
,而 j
被自动装箱为 Long
,而方法 test
的声明要求其两个参数具有相同的类型。
2)i
和 j
都会被自动装箱为 Long
,代码会编译并运行,显示 i
和 j
相等。
但实际发生的是,i
被自动装箱为 Integer
,j
被自动装箱为 Long
,代码编译没有错误。这不是与 test
方法的声明相矛盾吗?允许这样的代码的原因是什么?
英文:
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");
}
}
}
In the code snippet above I am expecting one of the following two things to happen:
-
There will be a compiler error, because
i
is autoboxed toInteger
andj
is autoboxed toLong
and the declaration of the methodtest
requires that both of its arguments are of the same type. -
Both
i
andj
to be autoboxed to Long and the code to compile and run showing thati
andj
are equal.
But what happens actually is i
is autoboxed to Integer
and j
is autoboxed to Long
and the code compiles without error. Doesn't this contradict with the declaration of test
? What is the reason to allow such code?
答案1
得分: 3
如果将 i
装箱为 Integer
,并且将 j
装箱为 Long
,仍然可以合法地调用名为 test
的方法,其中假定其泛型类型为 java.lang.Number
,它是 Integer
和 Long
的超类型。
实际上,您可以使用 任意 两个对象调用您的 test
方法,因为 T
可以被视为基本类型 Object
。方法上的泛型不限制其参数。
英文:
If i
is boxed to an Integer
and j
is boxed to a Long
, it's still legal to call the method test
with its generic type assumed to be java.lang.Number
, which is a supertype of both Integer
and Long
.
In fact, you can call your test
method with any two objects, because T
can be taken as the base type Object
. The generics on the method do not restrict its arguments at all.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论