名称冲突 - 具有相同的擦除但在方法参数generic中不会覆盖另一个

时间:2017-08-29 17:46:51

标签: java generics

我已阅读有关Name clash - have the same erasure yet neither overrides the other的所有问题和答案,但仍无法理解如何解决问题。所以,

@Dependent
public class SimpleFoo {}

@Dependent
public class AdvancedFoo extends SimpleFoo {}

@Dependent
public class Parent {

    @Inject
    protected void setFooInstance(Instance<? extends SimpleFoo> instance) {}
}

@Dependent
public class Child extends Parent {

    @Override
    protected void setFooInstance(Instance<AdvancedFoo> instance) {} //Error here
}

如何解决?

3 个答案:

答案 0 :(得分:4)

问题是Child类声明覆盖以下方法:

@Override
protected void setFooInstance(Instance<AdvancedFoo> instance) {} //Error here

但是Parent类声明了一个具有明显签名的setFooInstance方法:

protected void setFooInstance(Instance<? extends SimpleFoo> instance) {}

1)以这种方式覆盖Child类:

public class Child extends Parent {

    @Override
    protected void setFooInstance(Instance<? extends SimpleFoo> instance){... }
}

或2)其他方式:如果要强制子类中的覆盖方法声明特定的SimpleFoo,请使Parent类成为使用SimpleFoo参数化的泛型类或它的子类:

@Dependent
public class Parent <T extends SimpleFoo>{

    @Inject
    protected void setFooInstance(Instance<T> instance) {...}
}

现在可以声明Child类:

@Dependent
public class Child extends Parent<AdvancedFoo> {

    @Override
    protected void setFooInstance(Instance<AdvancedFoo> instance) {...}  
}

答案 1 :(得分:2)

如果将Child变为泛型类,则可以执行所需操作。然后让Parent扩展特定类型的Child,如图所示。

public class Child<T extends SimpleFoo> {
    protected void setFooInstance(Instance<T> instance) {}
}

public class Parent extends Child<AdvancedFoo> {
    @Override
    protected void setFooInstance(Instance<AdvancedFoo> instance) {}
}

顺便说一下,你的命名有点令人困惑。大多数人都希望Child延长Parent - 而不是相反。

答案 2 :(得分:1)

您希望Parent.setFooInstance可以使用Instance< SimpleFoo>的所有可能后代进行调用。对于Child类型的对象不适用,因为您只能将Instance<Advanced>作为参数。因此它不会以这种方式覆盖。否则只知道调用Parent的{​​{1}}类可能会调用错误类型的对象。 因此,您可以将setFooInstance方法的参数限制为Parent,或允许AdvancedFoo同时处理Child.setFooInstance的后代。