Java 为什么铸造ArrayList';超类的泛型不起作用?
有人能给我解释一下为什么下面代码示例中标记为Java 为什么铸造ArrayList';超类的泛型不起作用?,java,generics,casting,Java,Generics,Casting,有人能给我解释一下为什么下面代码示例中标记为//这一行出现编译错误(为什么?)的行不起作用吗 import java.util.ArrayList; public class GenericCastCheck { class A{ } class B extends A{ } public static void main(String[] args) { A aObject = new A(); B bObjec
//这一行出现编译错误(为什么?
)的行不起作用吗
import java.util.ArrayList;
public class GenericCastCheck {
class A{
}
class B extends A{
}
public static void main(String[] args) {
A aObject = new A();
B bObject = new B();
//this line works fine
aObject = bObject;
//this line gives a compile (expected)
bObject = aObject;
ArrayList<A> aList = new ArrayList<A>();
ArrayList<B> bList = new ArrayList<B>();
//this line gives a compile error (why?)
aList = bList;
//this line gives a compile error (expected)
bList = aList;
}
}
import java.util.ArrayList;
公共类GenericCastCheck{
甲级{
}
B类扩展了A类{
}
公共静态void main(字符串[]args){
A对象=新A();
B对象=新的B();
//这条线很好用
a对象=b对象;
//此行给出一个编译(预期)
b对象=a对象;
ArrayList aList=新的ArrayList();
ArrayList bList=新的ArrayList();
//这一行给出了一个编译错误(为什么?)
aList=bList;
//此行给出一个编译错误(预期)
布利斯特=伊斯兰主义者;
}
}
具体地说,当我们说bList
属于ArrayList
类型时,这不意味着它的每个元素都是B
的实例吗?如果是这样,那么如果我们可以将B
的单个实例转换为A
,那么将其转换为ArrayList
有什么问题
谢谢。因为通用性很严格。它们不是共变的
ArrayList
与数组不同,泛型类是
既不是协变的也不是逆变的。
例如,列表
和
列表
是
其他:
//a是字符串的单个元素列表
列表a=新的ArrayList();
a、 添加(“foo”);
//b是对象的列表
列表b=a;//这是一个编译时错误
但是,可以使用泛型类型参数
包含通配符(用于
仅使用的额外类型参数
一次)。示例:给定一个需求
对于对列表进行操作的方法,
对于任何对象,则只有
可以在上执行的操作
对象是指
类型关系是可以保证的
为了安全
// a is a single-element List of String
List<String> a = new ArrayList<String>();
a.add("foo");
// b is a List of anything
List<?> b = a;
// retrieve the first element
Object c = b.get(0);
// This is legal, because we can guarantee
// that the return type "?" is a subtype of Object
// Add an Integer to b.
b.add(new Integer (1));
// This is a compile-time error;
// we cannot guarantee that Integer is
// a subtype of the parameter type "?"
//a是字符串的单个元素列表
列表a=新的ArrayList();
a、 添加(“foo”);
//b是任何东西的清单
清单b=a;
//检索第一个元素
对象c=b.get(0);
//这是合法的,因为我们可以保证
//返回类型“”是对象的子类型
//给b加一个整数。
b、 加(新整数(1));
//这是一个编译时错误;
//我们不能保证整数是正确的
//参数类型“”的子类型
也可以绑定通配符,例如“?
扩展Foo
”或“?super Foo
”的
上界和下界。
这允许对允许的数据进行细化
演出示例:给定一个列表,问题是:
ArrayList<A> aList = new ArrayList<A>();
ArrayList<B> bList = new ArrayList<B>();
aList = bList; // if this were valid...
aList.add(new A()); // ...what should happen here?
B b = bList.get(0); // ...and here?
ArrayList aList=new ArrayList();
ArrayList bList=新的ArrayList();
aList=bList;//如果这是有效的。。。
aList.add(新的A());/。。。这里会发生什么?
B=bList.get(0);/。。。这里呢?
如果对数组执行相同的操作,则在运行时第4行会出现ArrayStoreException。对于泛型集合,决定在编译时防止这种情况。Animesh
即使类B是A的子类型,ArrayList也不是ArrayList的子类型。它与B[]在同一行,不是A[]的子类型。这是两个独立的不相关类型。因为在Java中,C
和C
之间没有子类型关系,即使A
是B
的超类型,反之亦然
如果您对详细信息感兴趣,请在Wikipedia中查找co-/contra方差
注意,在Java数组中,数组是共变的,这意味着A[]
是B[]
的超类型,如果A
是B
的超类型。这就是为什么有时数组会出现奇怪的强制转换异常 非常感谢。我意识到我应该使用aList=newarraylist(bList)代码>而不是编译也很好的aList=bList
。)
ArrayList<A> aList = new ArrayList<A>();
ArrayList<B> bList = new ArrayList<B>();
aList = bList; // if this were valid...
aList.add(new A()); // ...what should happen here?
B b = bList.get(0); // ...and here?