Java Enum definition

后端 未结 7 673
孤独总比滥情好
孤独总比滥情好 2020-11-22 17:24

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

class Enum>
         


        
7条回答
  •  孤街浪徒
    2020-11-22 17:55

    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
    

    Now if you check the constraints, we've got Enum - so E=StatusCode. Let's check: does E extend Enum? 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 implements Comparable. 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
      where TMessage : IMessage 
      where TBuilder : IBuilder
    
    public interface IMessage
      where TMessage : IMessage 
      where TBuilder : IBuilder
    

    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 {}
    public class Second extends Enum {}
    

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

提交回复
热议问题