小编典典

Java 枚举定义

all

我以为我非常了解 Java 泛型,但后来我在 java.lang.Enum 中遇到了以下内容:

class Enum<E extends Enum<E>>

有人可以解释如何解释这个类型参数吗?提供可以使用类似类型参数的其他示例的奖励积分。


阅读 87

收藏
2022-08-20

共1个答案

小编典典

这意味着枚举的类型参数必须从本身具有相同类型参数的枚举派生。这怎么可能发生?通过使类型参数成为新类型本身。因此,如果我有一个名为 StatusCode
的枚举,它将相当于:

public class StatusCode extends Enum<StatusCode>

现在,如果您检查约束,我们得到了Enum<StatusCode>-so
E=StatusCode。让我们检查一下:EextendEnum<StatusCode>吗?是的!我们没事。

您可能会问自己这样做的意义何在 :) 好吧,这意味着 Enum 的 API 可以引用自身 - 例如,能够说Enum<E>implements
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
的用户并不需要真正关心这一点,但这是一项很好的工作 - 它非常复杂,并且需要多次迭代才能到达它的位置。

编辑:请注意,这不会阻止您创建使用类型参数的奇怪类型,该类型参数本身是可以的,但不是同一类型。 目的是在正确 的情况下给予好处,而不是在 错误
的情况下保护您。

因此,如果Enum无论如何都没有在 Java 中“特别”处理,您可以(如注释中所述)创建以下类型:

public class First extends Enum<First> {}
public class Second extends Enum<First> {}

Second会实施Comparable<First>而不是Comparable<Second>......但First它本身会很好。

2022-08-20