我有一个在扩展参数化类型的类型上参数化的接口(interface),并且该接口(interface)包含一个需要被扩展类型的类型参数的方法。在代码中,这就是我想要的:
class Thingy<X> { ... }
interface Foo<P extends Thingy<?>> {
<T> T frobnicate(P<T> a);
}
但这不能编译。为了正确frobnicate
一个Thingy
,有必要知道它的Thingy
类型,还有一些Foo
> 可能专门用于处理特定类型的 Thingy
(异常(exception)是它们需要能够处理任何类型 T
任何 Thingy
已参数化)。
(顺便说一句,我已经发现 these questions 。前者只需要一个通用参数;我不在乎这里是否需要一个、两个或五个,只要有一些解决方案.后者在与我的 Foo
对应的类中具有特定类型而不是通配符,因此据我所知,那里的解决方案不适用。)
编辑:
由于我打算拥有的 Thingy
子类数量很少,因此我可以通过子类化 Thingy
并创建另一个接口(interface)来处理这些子类来获得相同的效果:
interface Foo {
<T> T frobnicate(Thingy<T> a);
}
class SpecialThingy<T> extends Thingy<T> { ... }
interface Bar {
<T> T frobnicate(SpecialThingy<T> a);
}
这并不像我希望的那么优雅,但在这种情况下它可以完成工作。
最佳答案
而不是使用扩展 Thingy<T>
的类型参数,仅对 T
使用类型参数并添加 Thingy
部分到需要的地方:
class Thingy<X> { }
interface Foo<X> {
X frobnicate(Thingy<X> a);
}
或者如果您需要使用 Thingy 的特定子类,那么这样怎么样?
class Thingy<X> { }
interface Foo<X, T extends Thingy<X>> {
X frobnicate(T a);
}
如果您需要更复杂的东西,那么最简单的事情就是只进行运行时类型检查。有时,泛型会产生比其值(value)更多的不必要的复杂性。
通过更好的设计,您也有可能避免使用泛型来表达此类内容。要对此提出建议,有必要更多地了解 Thingies 的使用方式,并提供比 Thingies 和 Foos 更具体的示例。
编辑:
既然要求是Thingy的类型参数不能事先知道,那么这应该是唯一的选择:
interface Foo {
<T> T frobnicate(Thingy<T> a);
}
关注Liskov substitution principle并使其适用于 Thingy 的所有实现。如果代码只能适用于 Thingy 的某些子类型,那么我认为您不能用泛型来表达它(它需要为类型参数提供类型参数),唯一的选择是进行运行时类型检查。运行时类型检查是一种代码味道,因此最好修复设计,以便不再需要它。
关于java - 如何参数化使用通配符参数扩展类型的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2356043/