Java 泛型的泛型

2022-09-04 01:40:13

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

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项:用接口模拟可扩展枚举。尽管我想说伟大的头脑是一样的......那就太狂妄了!


答案 1

TextFragment<E>需要说两件事。E

  • 它“延伸” 。TextFragmentMode<E>
  • 为此,您还必须将其限制为 扩展 。Enum<E>

由于Java继承的不稳定,你需要反过来写:

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

答案 2

问题是你试图使 E 扩展 ,它们不是相关的类型。哪种类型可以同时满足这两个约束?TextFragmentModeEnumE

我怀疑你想要个类型参数,如下所示:

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

现在,您已经在不同的类型参数上表达了每个约束,并且它们都有意义 - 您绝对可以找到一个哪个是枚举,一个是.但是,这非常复杂...EMTextFragmentMode<E>

...你肯定需要它成为这个通用的吗?你会在课堂上做什么?你能不能把 a 作为构造函数参数(或其他什么),然后再次在一个类型参数中使其泛型?MTextFragmentMode<E>