多级Java通用继承使用扩展通用参数

时间:2012-07-19 12:32:43

标签: java generics

我有

public class First<T> {}

public class Second<T extends SomeConcreteClass> extends First<T> {}

public class Third<T> extends Second<T> {} //Compile-time error

我收到编译时错误

Type argument T is not with bounds of type-variable T.

当我构造Third时,我希望能够将泛型参数赋予SomeConcreteClass(或其派生类),并且如果我已经抛出运行时错误提供了一个不属于SomeConcreteClass继承层次结构的类型。

我认为Second声明中的规范只会向下传播,即它应该隐含在Third的声明(以及任何实例化)中。

错误是什么?

4 个答案:

答案 0 :(得分:19)

你需要的只是

public class Third<T extends SomeConcreteClass> extends Second<T>

您只需重新指定绑定即可。它不像你想象的那样传播。

(我不是肯定的原因,但我有一些猜测 - 如果它是Third<T> extends Second<Foo<T>>怎么办?T上的适当界限不明显,如果有的话相反,它只是不会自动传播;你必须指定它。)

答案 1 :(得分:1)

你的边界限制向下传播。

如果您将上面的代码放在通用术语中,您将清楚地看到受限制的声明。此外,任何进一步的继承还需要保持或进一步缩小该限制。例如:

public class First<T> {}

public class Second<U, T1 extends U> extends First<T1> {}

public class Third<V, T2 extends V> extends Second<V,T2> {} 

请注意,现在很清楚,您无法拥有

public class Third<T> extends Second<T> {} 

因为您缺少T2所需的Second<V,T2>类型信息。 当您使用具体类时,此限制将变为隐式。

答案 2 :(得分:1)

在我们的案例中,您可以替换它:

public class Third<T> extends Second<T> {}

用这个:

public class Third extends Second<SomeConcreteClass> {}

要在构造函数中使用T,否则在代码中使用T类型的成员字段,那么您可以这样做:

VB2 extends VB1<Frag2>
...
public VB2(Frag2 frag){...

VB1<T extends Frag1> extends CommonVB<T>
...
public V1(T frag){... /// notice the T

CommonV<T extends CommonFragBase> extends BaseVB<T>
...
public CommonVB(T controller) {...

BaseVB<T extends CommonFragBase>

有效。重要的是具体类的泛型必须指定实际的具体片段类,以便VB类中的其他代码访问它的方法。

答案 3 :(得分:0)

public class Third<T> extends Second<T> {}

这是一个约束不匹配。当您刚刚指定第二个类型为T而不是扩展SomeConcreteClass时,您不能使用泛型T扩展Second。当你扩展Second时,你需要使用SomeConcreteClass范围内的东西。

public class Third<T> extends Second<ClassThatExtendsSomeConcreteClass> {}

或只是

public class Third<T> extends Second<SomeConcreteClass> {}