java - 如何参数化使用通配符参数扩展类型的类型?

标签 java generics

我有一个在扩展参数化类型的类型上参数化的接口(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/

相关文章:

java - 嵌入式的 JPA 2 XML 映射,以便它与 Hibernate 元模型生成器一起工作

java - Android Coverflow 起始位置

java - 如何解决 java 中的这种不兼容类型?

java - jfreechart setbackgroundpaint 不做任何事情

java - 通过 SSH 连接时无法推送 git 更新和运行 Unix 命令

java - 如何将文本仅加密为纯文本字符串

c# - 实现通用存储库模式 - 实体键类型

java - 抽象方法中的通用列表

Swift 编译器在 switch 语句上崩溃,需要解决方法

scala - Spark AccumulatorParam 通用参数