Java Enum definition

2022-08-31 06:49:22

我以为我对Java泛型的理解很好,但后来我在java.lang.Enum中遇到了以下几点:

class Enum<E extends Enum<E>>

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


答案 1

这意味着枚举的类型参数必须派生自枚举,而枚举本身具有相同的类型参数。怎么会这样?通过将类型参数作为新类型本身。因此,如果我有一个名为StatusCode的枚举,它将等效于:

public class StatusCode extends Enum<StatusCode>

现在,如果您检查约束,我们得到了 - 所以.让我们检查一下:是否扩展?是的!我们没事。Enum<StatusCode>E=StatusCodeEEnum<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的用户不需要真正关心这一点 - 它非常复杂,并且经过几次迭代才能到达它的位置。

编辑:请注意,这并不能阻止您创建奇数类型,这些类型使用类型参数,该参数本身是可以的,但不是同一类型。目的是在正确的情况下提供利益,而不是保护您免受错误案例的影响。

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

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

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


答案 2

以下是Java Generics and Collections一书中解释的修改版本:我们有一个声明Enum

enum Season { WINTER, SPRING, SUMMER, FALL }

它将扩展到一个类

final class Season extends ...

其中 是枚举的某种参数化基类。让我们弄清楚那必须是什么。好吧,其中一个要求是它应该实现 。因此,我们将需要...SeasonComparable<Season>

Season extends ... implements Comparable<Season>

你可以用什么来让它工作?鉴于它必须是 的参数化,唯一的选择是 ,这样你就可以拥有:...EnumEnum<Season>

Season extends Enum<Season>
Enum<Season> implements Comparable<Season>

因此,在诸如 之类的类型上进行参数化。从中抽象出来,你得到的参数是满足以下条件的任何类型:EnumSeasonSeasonEnum

 E extends Enum<E>

Maurice Naftalin(Java Generics and Collections合著者)