Java枚举定义 [英] Java Enum definition

查看:239
本文介绍了Java枚举定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  Enum< E扩展枚举< E> 

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

解决方案

这意味着枚举的类型参数从本身具有相同类型参数的枚举派生。怎么会这样呢?通过将type参数设置为新类型本身。所以如果我有一个名为StatusCode的枚举,它将相当于:

  public class StatusCode extends Enum< StatusCode> 

现在,如果您检查约束,我们有枚举< StatusCode> - 所以 E = StatusCode 。让我们检查一下: E extend 枚举< StatusCode> ?是!我们没关系。



你可能会问自己这点是什么:)那么这意味着枚举的API可以引用自己 - 例如可以说 Enum< E> 实现 Comparable< E> 。基类能够进行比较(在枚举的情况下),但它可以确保它只比较正确的枚举类型。 (编辑:几乎看到编辑在底部。)



我在我的C#Port of ProtocolBuffers中使用了类似的东西。有消息(不可变)和建设者(可变,用于构建消息) - 并且它们作为成对的类型。涉及的接口是:

  public interface IBuilder< TMessage,TBuilder> 
其中TMessage:IMessage< TMessage,TBuilder>
其中TBuilder:IBuilder< TMessage,TBuilder>

public interface IMessage< TMessage,TBuilder>
其中TMessage:IMessage< TMessage,TBuilder>
其中TBuilder:IBuilder< TMessage,TBuilder>

这意味着从消息中可以得到一个合适的构建器(例如,获取一个消息的副本并更改一些位),并从构建器中,您可以在完成构建后获得适当的消息。这是一个很好的工作,API的用户不需要真正关心这个 - 这是非常复杂的,并采取了几次迭代到达它的位置。



编辑:请注意,这并不妨碍您创建使用类型参数的奇怪类型,该类型参数本身是可以的,但是不是相同的类型。目的是在正确的案例中给予利益,而不是保护您免受错误的案例。



所以如果枚举在Java中没有特别处理,您可以(如注释中所述)创建以下类型:

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

第二个将实现 Comparable< First> 而不是 Comparable< Second> ...但首先本身会很好。


I thought I understood Java generics pretty well, but then I came across the following in java.lang.Enum:

class Enum<E extends Enum<E>>

Could someone explain how to interpret this type parameter? Bonus points for providing other examples of where a similar type parameter could be used.

解决方案

It means that the type argument for enum has to derive from an enum which itself has the same type argument. How can this happen? By making the type argument the new type itself. So if I've got an enum called StatusCode, it would be equivalent to:

public class StatusCode extends Enum<StatusCode>

Now if you check the constraints, we've got Enum<StatusCode> - so E=StatusCode. Let's check: does E extend Enum<StatusCode>? Yes! We're okay.

You may well be asking yourself what the point of this is :) Well, it means that the API for Enum can refer to itself - for instance, being able to say that Enum<E> implements Comparable<E>. The base class is able to do the comparisons (in the case of enums) but it can make sure that it only compares the right kind of enums with each other. (EDIT: Well, nearly - see the edit at the bottom.)

I've used something similar in my C# port of ProtocolBuffers. There are "messages" (immutable) and "builders" (mutable, used to build a message) - and they come as pairs of types. The interfaces involved are:

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>

This means that from a message you can get an appropriate builder (e.g. to take a copy of a message and change some bits) and from a builder you can get an appropriate message when you've finished building it. It's a good job users of the API don't need to actually care about this though - it's horrendously complicated, and took several iterations to get to where it is.

EDIT: Note that this doesn't stop you from creating odd types which use a type argument which itself is okay, but which isn't the same type. The purpose is to give benefits in the right case rather than protect you from the wrong case.

So if Enum weren't handled "specially" in Java anyway, you could (as noted in comments) create the following types:

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

Second would implement Comparable<First> rather than Comparable<Second>... but First itself would be fine.

这篇关于Java枚举定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆