Gel*_*ang 8 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 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>());
}
}
Run Code Online (Sandbox Code Playgroud)
该语句new TestMain().test(new ArrayList<B>(), new ArrayList<C>())出现编译错误:
绑定不匹配:类型TestMain的泛型方法测试(T,T)不适用于参数
(ArrayList<B>, ArrayList<C>).推断类型ArrayList<? extends A>不是有界参数的有效替代<T extends A>
然而:
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<B>(), new ArrayList<C>()) --> compiled ok
Run Code Online (Sandbox Code Playgroud)
如果我们在方法名称之前定义泛型,那么第二个泛型List参数的类型似乎必须与第一个参数的类型相同.但是如果我们在参数中定义泛型,则没有限制.
它是编译程序的功能还是错误?有关于它的一些文件吗?
pol*_*nts 18
绝对没有错误; 你只是误解了泛型中的子类型规则.
既然我们有B extends A:
B 是一个子类型 Ainstanceof B也是一个instanceof A由于Java数组是协变的:
B[] 是一个子类型 A[]instanceof B[]也是一个instanceof A[]但是,Java泛型是不变的:
List<B> 不是的子类型 List<A>instanceof List<B>不是instanceof List<A>.当您具有以下通用方法声明时:
public <T extends A> void test(List<T> a, List<T> b)
Run Code Online (Sandbox Code Playgroud)
然后,正如此处明确说明的那样,a并且b必须两者具有相同的类型List<T>,对于某些类型参数的捕获转换<T extends A>.
由于List<B>和List<C>是两种不同的类型,您不能将它们作为实际参数混合使用test.而且,即使B并且C是亚型A,泛型也是不变的,所以既不是List<B>也不List<C>是List<A>.
从而,
test(new ArrayList<B>(), new ArrayList<C>()); // error!!! doesn't compile!!!
Run Code Online (Sandbox Code Playgroud)
不编译,这是预期的行为.
java.lang.ArrayStoreException
关于泛型类型规则:
List<Animal> animals = new ArrayList<Dog>()?List是从不同的List<Object>是从一不同的List<?>使用super和extends:
Java Generics: What is PECS?
extends消费者super"super和之间有什么区别extends<E extends Number>和之间有什么区别<Number>?List<? extends Number>数据结构?(你不能!)关于实际的通用错误:
这不是一个错误,只是泛型是复杂的.尝试将第二种测试方法更改为:
public <T extends A, K extends A> void test(List<T> a, List<K> b) {
Run Code Online (Sandbox Code Playgroud)
基本上在你所拥有的东西中没有类型T可以满足你传入的东西,不像第一种方法,其中B和C只是被视为A.这种行为的实际名称逃脱了我但是应该有很多文献中的例子.
简而言之,即使B是A的孩子,List <B>也不是List <A>的孩子.
| 归档时间: |
|
| 查看次数: |
2630 次 |
| 最近记录: |