Java泛型-令人困惑的行为 [英] Java Generics - Confusing behavior
问题描述
我无法理解为什么我在这里遇到编译错误.让我分享一些简单的代码.以下代码块可以正常工作:
I'm having trouble understanding why I'm getting a compilation error here. Let me share some simple code. The following block of code works fine:
public class Test {
public static void main(String[] args) {
String[] arr = new String[0];
MethodA(arr);
}
public static <E> void MethodA(E[] array) {
Integer[] intArray = new Integer[0];
MethodB(array, intArray);
}
public static <E> void MethodB(E[] array, E[] secondArray) {
//Stuff
}
}
当我向MethodB添加新的通用List参数并从MethodA调用它时,就会出现问题:
The problem arises when I add a new generic List parameter to MethodB, calling it from MethodA:
public class Test {
public static void main(String[] args) {
String[] arr = new String[0];
MethodA(arr);
}
public static <E> void MethodA(E[] array) {
Integer[] intArray = new Integer[0];
List<E> someList = new ArrayList<E>();
MethodB(array, intArray, someList);
}
public static <E> void MethodB(E[] array, E[] secondArray, List<E> list) {
//Stuff
}
}
这给了我以下错误:
线程"main"中的异常java.lang.Error:未解决的编译问题: Test类型的方法MethodB(E [],E [],List)不适用于参数(E [],Integer [],List)
Exception in thread "main" java.lang.Error: Unresolved compilation problem: The method MethodB(E[], E[], List) in the type Test is not applicable for the arguments (E[], Integer[], List)
似乎是在告诉我将参数从E []更改为Integer [],这很奇怪,因为直到我引入List参数后,它才抱怨这种事情.同样,我觉得我一定在某个地方犯了一个愚蠢的错误,但我无法弄清楚.任何帮助,将不胜感激!谢谢!
It seems to be telling me to change the parameter from E[] to Integer[], which is weird because it did not complain about such a thing until after I introduced the List parameter. Again, I feel like I must be making a silly mistake somewhere, but I can't figure it out. Any help would be appreciated! Thanks!
推荐答案
在第一个示例中,您要使用String[]
和Integer[]
调用MethodB
.
In the first example, you're calling MethodB
with a String[]
and an Integer[]
.
由于数组是协变量"的-例如,您可以将String[]
强制转换为Object[]
,因此它将E的MethodB
版本与Object
一起调用.
Since arrays are "covariant" - meaning, for example, you can cast a String[]
to an Object[]
, it calls the version of MethodB
with Object
for E.
在第二个示例中,它很相似,但是您也有一个List<E>
.通用类的 not 不能以与数组相同的方式工作-您不能将List<String>
强制转换为List<Object>
.因此,将E设为Object
(或除MethodA
中的E之外的任何其他值)将是无效的,因为此后无法转换第三个参数,并且由于将E设为String
也将无效那么第一个参数将无法转换.因此,没有适用于E
的类型.
In the second example, it's similar, but you also have a List<E>
. Generic classes do not work the same way of arrays - you cannot cast a List<String>
to a List<Object>
. So it would be invalid for E to be Object
(or anything other than whatever E is in MethodA
) since then the third parameter couldn't be converted, and it would also be invalid for E to be String
since then the first parameter couldn't be converted. So there is no type that works for E
.
注意:如果在main
中将String
更改为Integer
,即使E
可能是Integer
,它仍然不会编译.那是因为编译器不知道除Integer
之外,从未调用MethodA
.
Note: If you changed String
to Integer
in main
, it still wouldn't compile, even though E
could be Integer
. That's because the compiler doesn't know that MethodA
is never called with anything other than Integer
.
这篇关于Java泛型-令人困惑的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!