Java通用方法的擦除和继承

问题描述 投票:1回答:1

我遇到了javas泛型和重写方法的问题。想象一下,我有一个像树一样深的类层次结构。顶级类定义了方法foo,该方法带有1个类型为Strategy的参数。策略具有通用类型参数。

我的类层次结构中的每个类都需要重写foo以限制可以传递的策略类型,以便策略的通用类型参数与声明的类匹配。下面是一个示例:

abstract class TopLevelClass {
    void foo(Strategy<TopLevelClass> s) {/*...*/}
}
class MidLevelClass extends TopLevelClass {
    void foo(Strategy<MidLevelClass> s) {/*...*/}
}
class LowLevelClass extends MidLevelClass  {
    void foo(Strategy<LowLevelClass> s) {/*...*/}
}

上面的代码在Java中NOT进行编译。编译时错误为:

名称冲突:MidLevelClass类型的foo(Strategy)方法与TopLevelClass类型的foo(Strategy)具有相同的擦除,但不会覆盖它

我怀疑这很容易解决。我可以只使用原始类型并依靠运行时类型检查,但是我宁愿保持类型安全。在不牺牲类型层次结构或类型安全性的前提下,我该怎么做?请注意,在构造函数中传递策略IS NOT对我来说是一个选择!必须可以在对象的整个生命周期内多次调用foo。

java generics inheritance type-safety
1个回答
1
投票

如果您担心擦除,则只需对单独的方法使用单独的方法名称:

abstract class TopLevelClass {
    void fooTop(Strategy<TopLevelClass> s) {/*...*/}
}
class MidLevelClass extends TopLevelClass {
    void fooMid(Strategy<MidLevelClass> s) {/*...*/}
}
class LowLevelClass extends MidLevelClass  {
    void fooLow(Strategy<LowLevelClass> s) {/*...*/}
}

但是,我怀疑擦除不是您的问题。您大概想重写相同的方法。

您可能要添加通配符:

abstract class TopLevelClass {
    void foo(Strategy<? super TopLevelClass> s) {/*...*/}
}
class MidLevelClass extends TopLevelClass {
    void foo(Strategy<? super MidLevelClass> s) {/*...*/}
}
class LowLevelClass extends MidLevelClass  {
    void foo(Strategy<? super LowLevelClass> s) {/*...*/}
}

或在类中添加类型参数以用作方法中的类型参数。

abstract class TopLevelClass<T extends TopLevelClass> {
    void foo(Strategy<T> s) {/*...*/}
}
class MidLevelClass<T extends MidLevelClass> extends TopLevelClass<T> {
    void foo(Strategy<T> s) {/*...*/}
}
class LowLevelClass<T extends LowLevelClass> extends MidLevelClass<T>  {
    void foo(Strategy<T> s) {/*...*/}
}
© www.soinside.com 2019 - 2024. All rights reserved.