这意味着枚举的类型参数必须派生自本身具有相同类型参数的枚举。怎么会发生这种事呢?通过使类型参数成为新类型本身。因此,如果我有一个名为 StatusCode 的枚举,它将相当于:
public class StatusCode extends Enum<StatusCode>
现在如果你检查约束条件,我们有Enum<StatusCode>
- so E=StatusCode
。让我们检查一下:是否E
extend Enum<StatusCode>
?是的!我们没事。
您可能会问自己这有什么意义:) 好吧,这意味着 Enum 的 API 可以引用自身 - 例如,能够说Enum<E>
实施Comparable<E>
。基类能够进行比较(在枚举的情况下),但它可以确保它只比较正确类型的枚举。 (编辑:嗯,几乎 - 请参阅底部的编辑。)
我在 ProtocolBuffers 的 C# 端口中使用了类似的东西。有“消息”(不可变)和“构建器”(可变,用于构建消息) - 它们以类型对的形式出现。涉及到的接口有:
public interface IBuilder<TMessage, TBuilder>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
public interface IMessage<TMessage, TBuilder>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
这意味着您可以从消息中获取适当的构建器(例如,获取消息的副本并更改一些位),并且在完成构建后可以从构建器中获取适当的消息。不过,API 的用户不需要真正关心这一点,这是一件好事——它非常复杂,并且需要多次迭代才能达到它的目的。
编辑:请注意,这并不能阻止您创建奇怪的类型,这些类型使用的类型参数本身没问题,但类型不同。其目的是为了给人们带来好处right情况而不是保护您免受wrong case.
So if Enum
无论如何,在 Java 中都没有“特殊”处理,您可以(如注释中所述)创建以下类型:
public class First extends Enum<First> {}
public class Second extends Enum<First> {}
Second
将实施Comparable<First>
而不是Comparable<Second>
... but First
本身就很好。