【问题标题】:Java generics of generics ofJava泛型的泛型
【发布时间】:2010-11-22 17:23:42
【问题描述】:

我有一个代表文本片段的通用类。该文本片段可能具有多种不同模式(不同类型的突出显示)中的任何一种。这些模式由枚举表示。每个项目的枚举可能不同,但它必须实现一个接口,该接口提供一种方法来组合其中的两个(可以突出显示并加粗)。所以我有一个界面:

public interface TextFragmentMode<E extends Enum<E>> {
    /**
     * Will combine the supplied mode with the current mode and return the
     * result.
     * 
     * @param mode The mode to combine with.
     * @return The combined mode.
     */
    public E combine( E mode );
}

然后我的 TextFragment 是一个包含文本字符串和模式的容器。但是当我尝试声明类时:

public class TextFragment<E extends TextFragmentMode<E extends Enum<E>>> {
    StringBuilder text;
    E mode;
    ...

我收到以下错误:

令牌“扩展”的语法错误,预期

根据eclipse语法高亮,指的是

E extends Enum<E>

部分代码。有谁知道我做错了什么?我一定遗漏了一些关于泛型的东西......

--------------------- 编辑 -------------------

我终于花时间阅读 Josh Bloch 的 Effective Java(第二版),结果发现他将这个用例作为 第 34 条:使用接口模拟可扩展枚举。就像我想说的一样伟大的思想……那太冒昧了!

【问题讨论】:

  • 谢谢我在 P 上苦苦挣扎 :)

标签: java generics enums


【解决方案1】:

TextFragment&lt;E&gt; 需要对E 说两件事。

  • 它“扩展”TextFragmentMode&lt;E&gt;
  • 为此,您还必须将其限制为扩展 Enum&lt;E&gt;

由于 Java 继承不可靠,您需要反过来写:

public class TextFragment<E extends Enum<E> & TextFragmentMode<E>> {

【讨论】:

【解决方案2】:

问题是您试图让 E 扩展 TextFragmentMode Enum,它们不是相关类型。什么类型的E 会同时满足这两个约束?

我怀疑你想要两个类型的参数,像这样:

public class TextFragment<E extends Enum<E>, M extends TextFragmentMode<E>>

现在每个约束都在不同的类型参数上表示,它们都有意义 - 你肯定可以找到一个 E 是一个枚举,以及一​​个 M 这是一个 TextFragmentMode&lt;E&gt;。但是,它相当复杂......

...你一定需要它是这样通用的吗?你将在课堂上使用M 做什么?你能不能只将TextFragmentMode&lt;E&gt; 作为构造函数参数(或其他)并再次使其在一个类型参数中泛型?

【讨论】:

  • 好的,所以你的结果代码行是我得到的解决方案之一,但它让一切变得丑陋。然后,每次声明/实例化时,您都需要两个类型参数,而且它们本身有点长。您最终在类型名称上使用了 80 个字符。在实践中,我的实现类型是: public enum MyType implements TextFragmentMode 既是枚举又是 TextFragmentMode...
【解决方案3】:

你需要引入一个新的类型来解释 Enum 的边界

public class TextFragment<T extends Enum<T>, E extends TextFragmentMode<T>> {

【讨论】:

  • 再次(根据上面的评论)我不太喜欢这个(尽管它会起作用),因为它不优雅。它看起来非常难看,似乎应该有更好的方法来做到这一点。
【解决方案4】:

如果没有测试,我猜:

public class TextFragment<E extends TextFragmentMode<E>> {

嗯,简短的测试表明它似乎也不起作用......

【讨论】:

  • 不编译,因为你需要约束E extends Enum&lt;E&gt;,以便与TextFragmentMode兼容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多