我无法理解为什么我在这里收到编译错误。让我分享一些简单的代码。以下代码块正常工作:
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调用它:
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
}
}
这给了我以下错误:
线程中的异常&#34; main&#34; java.lang.Error:未解决的编译问题: Test类型中的方法B(E [],E [],List)不适用于参数(E [],Integer [],List)
似乎告诉我将参数从E []更改为Integer [],这很奇怪,因为在我引入List参数之前它并没有抱怨这样的事情。再一次,我觉得我必须在某个地方犯一个愚蠢的错误,但我无法弄明白。任何帮助,将不胜感激!谢谢!
答案 0 :(得分:7)
在第一个示例中,您使用MethodB
和String[]
来呼叫Integer[]
。
由于数组是“协变的” - 例如,您可以将String[]
强制转换为Object[]
,因此它会调用MethodB
的版本Object
在第二个示例中,它类似,但您也有一个List<E>
。通用类不以与数组相同的方式工作 - 您无法将List<String>
转换为List<Object>
。因此,对于E Object
(或除了MethodA
中的任何E之外的任何东西),它将无效,因为那时第三个参数无法转换,并且对于E来说它也是无效的String
从那时起第一个参数无法转换。因此,没有适用于E
的类型。
注意:如果您在String
中将Integer
更改为main
,即使E
可能是Integer
,它仍然无法编译。那是因为编译器不知道MethodA
永远不会被Integer
以外的任何东西调用。
答案 1 :(得分:1)
在方法B声明中对所有三个参数使用相同的泛型类型(E)。 您可以使用任何类型的参数(E),但对于所有3个参数必须相同。
尝试添加另一种泛型类型(T):
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, T> void MethodB(E[] array, T[] secondArray, List<E> list) {
//Stuff
}
}
或者,如果有需要,可以添加第三个,以便List不要求E与E []数组中的类型相同。
答案 2 :(得分:0)
MethodB要求所有三个参数都是相同的类型。但是你用E和Integer调用它。试试E [] intArray = null;和编译器不会编译