为什么Java类型擦除会更改目标集合的非通用类型?

问题描述 投票:0回答:2

首先,我来自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 type-erasure
2个回答
2
投票

当我用具体类型定义目标集合时,我希望该集合保留该类型

期望不正确。 Java中的泛型(几乎)是相关的“仅编译时”。

只有一个ArrayList类,并且可以使用Object类型的参数。当添加“错误类型”时,您从编译器得到的错误是:仅编译时。

当然,您可以创建您的own列表实现,该实现用一个具体的Class实例进行实例化,然后在运行时进行相应的检查。和update:您可以使用Collection类的帮助方法之一,例如checkedCollection()创建一个可以做到这一点的collection / list / set /...。

除此之外:

for(CA instance : result)
{
    //ClassCastException at second instance...

[这里有一个明确的演员表,您声称:结果列表中的所有对象都是CA对象,但显然不是全部。


0
投票

您正在通过以下方式进行未经检查的演员表

© www.soinside.com 2019 - 2024. All rights reserved.