java 为什么这种类型不是类型参数的有效替代品?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7032941/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is this type not a valid substitute for the type parameter?
提问by forty-two
I'm experimenting with using generics to support a configurable structure of delegating objects (decorators, wrappers). I want to build a chain of delegators that implements a target interface as well as a generic delegator interface.
我正在尝试使用泛型来支持委托对象(装饰器、包装器)的可配置结构。我想构建一个实现目标接口和通用委托接口的委托链。
I have this outline:
我有这个大纲:
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>();
}
}
But, when trying to instantiate the chain
variable, compiler complains:
但是,当尝试实例化chain
变量时,编译器会抱怨:
Bound mismatch: The type Test.FooDelegator is not a valid substitute for the bounded parameter
<T extends Test.Delegator<T>>
of the typeTest.DelegatorChain<T>
边界不匹配:类型 Test.FooDelegator 不是该类型的有界参数
<T extends Test.Delegator<T>>
的有效替代品Test.DelegatorChain<T>
I admit that generics is like magicto me, but I can somehow acknowledge that FooDelegator is not a Foo that extendsDelegator<Foo>, it simply implements both interfaces.
我承认泛型对我来说就像魔术一样,但我可以以某种方式承认 FooDelegator 不是扩展Delegator <Foo> 的 Foo,它只是实现了两个接口。
Given that it's clear what I want to accomplish, is there anything I can do w.r.t. generics to fix it, or am I just better of forgetting about it?
鉴于很明显我想要完成什么,有什么我可以用泛型来修复它,还是我最好忘记它?
采纳答案by Bohemian
Under your definition, a Delegator is a Delegator of itself (like Comparable is for example), however it seems the intention is that Delegator is a Delegator of a super class. Luckily, generics has a way of expressing this:
根据您的定义,委托人是自己的委托人(例如 Comparable 是),但似乎意图是委托人是超类的委托人。幸运的是,泛型有一种表达方式:
static class DelegatorChain<T extends Delegator<? super T>> {}
This says that the "Delagator type must be a super class of T". With this change, the rest of your original code compiles:
这表示“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>();
}
Also, anytime you use a generic super bound, your code looks really cool :)
此外,无论何时您使用通用超级绑定,您的代码看起来都非常酷:)
Note: This following was originally the "first option" in the question.
There is another way to get your code to compile, but it is inferior because it loses the connect between the Delegator type and what it's delegating from:
注意:以下最初是问题中的“第一个选项”。
还有另一种方法可以让你的代码编译,但它很差,因为它失去了 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 {}
回答by ScArcher2
It looks like this is what you are trying to do.
看起来这就是你想要做的。
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>();
}
Your initial example does not compile because the types are not correct. The Generic type in DelegatorChain is a "FooDelegator" but the generic type required in the Delegator is "Foo". You'll need the extra generic type parameter that i provided in my answer to make it work as you intended.
您的初始示例无法编译,因为类型不正确。DelegatorChain 中的泛型类型是“FooDelegator”,但 Delegator 中所需的泛型类型是“Foo”。您将需要我在回答中提供的额外泛型类型参数,以使其按预期工作。
You could also leave the constraint off entirely on DelegatorChain i.e. DelegatorChain.
您也可以完全取消对 DelegatorChain 的约束,即 DelegatorChain。
回答by Stefan Schubert-Peters
What should work instead is, if FooDelegator implements Delegator<FooDelegator>
or Foo implements Delegator<Foo>
. Because this is what you are requiring for the DelegatorChain: T implements Delegator<T>
.
应该起作用的是,如果FooDelegator implements Delegator<FooDelegator>
或Foo implements Delegator<Foo>
。因为这是您对 DelegatorChain 的要求:T implements Delegator<T>
。
Third alternative, which should work as well:
第三种选择,也应该有效:
DelegatorChain<T extends Delegator<F>, F> chain; ...