首先,我来自C#,但是我知道Java中的类型擦除。但是我不明白下面的代码示例...
当我用具体类型定义目标集合时,我希望该集合保留该类型。即使实际的收集是通用方法的结果。因此,如果分配了不适当的集合,我期望ClassCastException。但是没有异常发生,但是目标集合的内部类型在运行时发生了变化...稍后我迭代集合,在迭代过程中得到ClassCastExceptions ...难道我做错了什么?还是这种奇怪的行为是正确的?
//There are 2 classes. Both implementing the same interface.
class CA implements IA
class CB implements IA
public void method1()
{
//This is the target-collection. The Type is set to CA(!)
//In Java, I expect an exception here! Why does Java change the type of
//collection? This is very dangerous ... because I have defined a
//specific type. So I expect to get what I have defined.
Collection<CA> result = getInstances();
//Some Code...
//Time to iterate the instances
for(CA instance : result)
{
//ClassCastException at second instance...
}
}
public <T extends IA> Collection<T> getInstances()
{
//Resulting collection
Collection<T> instances = new LinkedList<T>();
for(int i = 0; i < 2; i++)
{
//In C#, an exception would occure exactly here.
//That would be sooo fine... :(
//I already wrote a solution for this. I use Class<T> to cast at
//this point. So thats not my question. I just want to understand
//why java is allowing to change the inner type of collection
T instance = (T)getInstance(i);
//Add the instance
instances.add(instance);
}
//At this point, the collection will containing CA and(!) CB instances...
return instances;
}
//Non-generic method!
public IA getInstance(int i)
{
if(i == 0)
return new CA();
else
return new CB();
}
当我用具体类型定义目标集合时,我希望该集合保留该类型
期望不正确。 Java中的泛型(几乎)是相关的“仅编译时”。
只有一个ArrayList类,并且可以使用Object
类型的参数。当添加“错误类型”时,您从编译器得到的错误是:仅编译时。
当然,您可以创建您的own列表实现,该实现用一个具体的Class
实例进行实例化,然后在运行时进行相应的检查。和update:您可以使用Collection类的帮助方法之一,例如checkedCollection()创建一个可以做到这一点的collection / list / set /...。
除此之外:
for(CA instance : result) { //ClassCastException at second instance...
[这里有一个明确的演员表,您声称:结果列表中的所有对象都是
CA
对象,但显然不是全部。
您正在通过以下方式进行未经检查的演员表