Java多个泛型集合参数编译错误

Java多个泛型集合参数编译错误,java,generics,collections,compiler-errors,Java,Generics,Collections,Compiler Errors,真奇怪!请先看一下代码: public class A {} public class B extends A {} public class C extends A {} public class TestMain { public <T extends A> void test(T a, T b) {} public <T extends A> void test(List<T> a, List<T> b) {}

真奇怪!请先看一下代码:

public class A {}

public class B extends A {}

public class C extends A {}

public class TestMain {

    public <T extends A> void test(T a, T b) {}

    public <T extends A> void test(List<T> a, List<T> b) {}

    public void test1(List<? extends A> a, List<? extends A> b) {}

    public static void main(String[] args) {
        new TestMain().test(new B(), new C());
        new TestMain().test(new ArrayList<C>(), new ArrayList<C>());
        new TestMain().test(new ArrayList<B>(), new ArrayList<C>());
        new TestMain().test1(new ArrayList<B>(), new ArrayList<C>());
    }
}
公共类A{}
公共类B扩展了{}
公共类C扩展了{}
公共类TestMain{
公共无效性检验(ta,tb){}
公共无效测试(列表a、列表b){}

public void test1(List这不是一个bug,只是泛型比较复杂。请尝试将第二个测试方法更改为:

    public <T extends A, K extends A> void test(List<T> a, List<K> b) {
公共无效测试(列表a、列表b){
基本上,在你所得到的东西中,没有一种类型T可以满足你所传递的东西,这与第一种方法不同,在第一种方法中,B和C只是被当作A。我不知道这种行为的实际名称,但在文献中应该有很多例子


简而言之,即使B是a的子对象,列表也不是List的子对象。

绝对没有bug;您只是误解了泛型中的子类型规则

因为我们有
B扩展了A

  • B
    a
  • B的
    实例也是A的
    实例
由于Java数组是协变的:

  • B[]
    a[]
  • B[]的
    实例
    也是A[]的
    实例
但是,Java泛型是不变的:

  • List
    不是
    List的子类型
    
    • Java数组子类型是协变的,不是类型安全的;泛型是不变的,是不安全的
相关问题 关于泛型类型规则:

    • 解释原始类型
      列表
      列表
      的不同之处,后者与
      列表
使用
super
扩展时:

    • 来自有效Java第二版:“生产者<代码>扩展
消费者<代码>超级
  • (你不能!)
  • 关于实际的通用错误:

        public <T extends A, K extends A> void test(List<T> a, List<K> b) {
    
    public <T extends A> void test(List<T> a, List<T> b) 
    
    test(new ArrayList<B>(), new ArrayList<C>()); // error!!! doesn't compile!!!