Java泛型 - 类型擦除的问题?

时间:2014-04-08 17:23:28

标签: java generics inheritance

我有一个泛型类CodominantPopulation,它是另一个泛型类SexualPopulation的子类,它本身是泛型类(Population)的子类。上述类定义如下:

public class CodominantPopulation<O extends CodominantOrganism> extends SexualPopulation<O> {

public CodominantPopulation(List<O> organisms) {
        super(organisms);
    }
    ...
}

public class SexualPopulation<O extends SexualOrganism> extends Population<O> {
    public SexualPopulation(List<O> organisms){
        super(organisms);
    }
    ...
}

上面的CodominiantOrganismSexualOrganism的子类,它本身是Organism的子类(可能是预期的)。在CodominantPopulation中,我调用了一个仅适用于CodominantOrganisms的函数,如下所示:

// in CodominantPopulation
for (O organism : population){
    // organism must be a CodominantOrganism
    CodominantGenotype.Dominance dominance = organism.getTraitDominance(trait);
    ...
}

尽管如此,运行时抛出:

Exception in thread "main" java.lang.ClassCastException: SexualOrganism cannot be cast to util.CodominantOrganism
    at CodominantPopulation.countDominance(CodominantPopulation.java:xx)
        ...

我不确定如何解释/修复此错误。我做了一些研究,似乎这可能与Java的类型擦除有关 - 这可能吗?我在编译程序之前将CodominantOrganism类型的对象传递给CodominantPopulation

编辑:Population的定义如下:

public class Population<O extends Organism> {
    List<O> population;

    public Population(List<O> organisms){
        this.population = new ArrayList<>();
        this.population.addAll(organisms);
    }
    ...
}

1 个答案:

答案 0 :(得分:1)

我的猜测是,泛型类型的问题较少,但使用继承,基于将尚未就绪的对象传递给超级。也许你有工厂方法或构造函数试图传递一个尚未制作的CodominantOrganism

这可能发生在几种方式。

class A
    A (X y) { f(y); }
    protected void f(X x) { }

class B
    B (X y) { super(y); f(y); }
    @Override
    protected void f(X x) { }

这里A的构造函数确实是B的f被调用,但是没有B。

运气好的时候,IDE会警告在构造函数中使用非final方法,但是同类型的其他模式也是可能的。也许使用FindBugs检查代码不一致。

我可能错了,但通用类型似乎不是罪魁祸首。