Java multiple generic collection parameters compile error
真奇怪!请先看一下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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(), new ArrayList<C>()); new TestMain().test1(new ArrayList(), new ArrayList<C>()); } } |
语句
Bound mismatch: The generic method test(T, T) of type TestMain is not applicable
for the arguments(ArrayList, ArrayList . The inferred type)
ArrayList extends A> is not a valid substitute for the bounded parameter
然而:
1 2 3 4 5 | new TestMain().test(new B(), new C()) --> compiled ok new TestMain().test(new ArrayList<C>(), new ArrayList<C>()) --> compiled ok new TestMain().test1(new ArrayList(), new ArrayList<C>()) --> compiled ok |
如果在方法名之前定义泛型,则第二个泛型
它是编译程序的一个特性还是一个缺陷?有关于它的文件吗?
绝对没有bug;您只是误解了泛型中的子类型规则。
因为我们有
B 是A 的一个亚型。instanceof B 也是instanceof A 。
因为Java数组是协变的:
B[] 是A[] 的一个亚型。instanceof B[] 也是instanceof A[] 。
然而,Java泛型是不变量的:
当您具有以下泛型方法声明时:
1 | public <T extends A> void test(List<T> a, List<T> b) |
那么,正如这里明确指出的,对于类型参数
由于
因此,
1 |
未编译,这是预期的行为。
也见- Java教程/泛型
- 子类型
- 野猫游戏更有趣
- jls 10.10数组存储异常和
java.lang.ArrayStoreException 。- Java数组子类型是协变的,不是类型化的;泛型是不变的,是。
相关问题
关于泛型类型规则:
- 有什么简单的方法来解释为什么我不能做
List ?animals = new ArrayList () - Java泛型(非)协方差
- 什么是原始类型,为什么不使用它?
- 解释原始类型
List 与List 的区别,后者与List> 不同。
- 解释原始类型
使用
Java Generics: What is PECS? - 从有效的Java第二版:"生产者EDCOX1,32,消费者EDCOX1,31"
- 在Java泛型中EDCOX1与31和EDCX1 32的区别是什么?
和 有什么区别?- 如何添加到
List extends Number> 数据结构中?(你不能!)
在实际的一般错误上:
- 泛型在Eclipse中编译和运行,但不在javac中编译
这不是一个bug,只是泛型很复杂。尝试将第二种测试方法更改为:
1 | public <T extends A, K extends A> void test(List<T> a, List<K> b) { |
基本上,在你所得到的东西中,没有一种类型t能满足你所传递的东西,不像第一种方法,其中b和c只是作为a来处理。这种行为的实际名称让我难以理解,但文献中应该有很多例子。
简而言之,即使b是a的子级,list也不是list的子级。