Java Generics - 令人困惑的行为

Fit*_*123 5 java generics

我无法理解为什么我在这里收到编译错误.让我分享一些简单的代码.以下代码块工作正常:

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
  }
}
Run Code Online (Sandbox Code Playgroud)

当我向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
  }
}
Run Code Online (Sandbox Code Playgroud)

这给了我以下错误:

线程"main"中的异常java.lang.Error:未解决的编译问题:类型Test中的方法MethodB(E [],E [],List)不适用于参数(E [],Integer [],List )

它似乎告诉我将参数从E []更改为Integer [],这很奇怪,因为在我引入List参数之前它并没有抱怨这样的事情.再一次,我觉得我必须在某个地方犯一个愚蠢的错误,但我无法弄明白.任何帮助,将不胜感激!谢谢!

use*_*751 7

在第一个例子中,你MethodB用a String[]和a 调用Integer[].

因为数组是"协变" -这意味着,例如,你可以投出String[]一个Object[],它调用的版本MethodBObject为E.

在第二个例子中,它是相似的,但你也有一个List<E>.泛型类就不能正常工作阵列以同样的方式-你不能施放List<String>List<Object>.因此,对于E来说Object(或者除了E之外的其他任何东西)都是无效的,MethodA因为那时第三个参数无法转换,并且对于E来说也是无效的,String因为那时第一个参数无法转换.所以没有适合的类型E.

注意:如果您更改StringIntegerin main,它仍然无法编译,即使E可能Integer.那是因为编译器不知道MethodA除了之外的任何东西都不会被调用Integer.