我正在尝试使用泛型来支持委托对象(装饰器,包装器)的可配置结构。我想构建一个实现目标接口和通用委托接口的委托链。
我有这个大纲:
class Test {
static interface Delegator<T> {}
static class DelegatorChain<T extends Delegator<T>> {}
static interface Foo {}
static class FooDelegator implements Delegator<Foo>, Foo {}
public static void main(String[] args) {
DelegatorChain<FooDelegator> chain = new DelegatorChain<FooDelegator>();
}
}
但是,在尝试实例化chain
变量时,编译器会抱怨:
绑定不匹配:Test.FooDelegator类型不能替代
<T extends Test.Delegator<T>>
类型的有界参数Test.DelegatorChain<T>
我承认泛型对我来说就像magic,但我可以以某种方式承认FooDelegator不是扩展 Delegator&lt; Foo&gt;的Foo,它只是实现了两个接口。
鉴于我想要完成的事情很清楚,我能做些什么吗?用于修复它的泛型,还是我最好忘记它?
答案 0 :(得分:9)
根据您的定义,Delegator本身就是一个Delegator(例如Comparable),但似乎意图是Delegator是超类的Delegator。幸运的是,泛型有一种表达方式:
static class DelegatorChain<T extends Delegator<? super T>> {}
这表示“Delagator类型必须是T的超类”。通过此更改,原始代码的其余部分将编译:
static interface Delegator<T> {}
static class DelegatorChain<T extends Delegator<? super T>> {}
static interface Foo {}
static class FooDelegator implements Delegator<Foo>, Foo {}
public static void main(String[] args) {
DelegatorChain<FooDelegator> chain = new DelegatorChain<FooDelegator>();
}
此外,无论何时使用通用超级绑定,您的代码看起来都很酷:)
注意:以下内容最初是问题中的“第一选项”
还有另一种方法可以让您的代码进行编译,但它是次要的,因为它失去了Delegator类型与委托代理之间的连接:
// Not recommended, but will allow compile:
static class FooDelegator implements Delegator<FooDelegator>, Foo {}
// However, this also compiles :(
static class FooDelegator implements Delegator<FooDelegator>, Bar {}
答案 1 :(得分:3)
看起来这就是你要做的事。
static interface Delegator<T> {
}
static class DelegatorChain<T extends Delegator<C>, C> {
}
static interface Foo {
}
static class FooDelegator implements Delegator<Foo>, Foo {
}
public static void main(String[] args) {
DelegatorChain<FooDelegator, Foo> chain = new DelegatorChain<FooDelegator, Foo>();
}
您的初始示例无法编译,因为类型不正确。 DelegatorChain中的Generic类型是“FooDelegator”,但Delegator中所需的泛型类型是“Foo”。您需要我在答案中提供的额外泛型类型参数,以使其按预期工作。
您也可以将约束完全保留在DelegatorChain上,即DelegatorChain。
答案 2 :(得分:0)
如果FooDelegator implements Delegator<FooDelegator>
或Foo implements Delegator<Foo>
,应该做什么。因为这是DelegatorChain所要求的:T implements Delegator<T>
。
第三种选择,也应该有效:
DelegatorChain<T extends Delegator<F>, F> chain; ...