我有
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
的声明(以及任何实例化)中。
错误是什么?
答案 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> {}