Java泛型-令人困惑的行为 [英] Java Generics - Confusing behavior

查看:87
本文介绍了Java泛型-令人困惑的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆