理解Java中的枚举

理解Java中的枚举,java,enums,Java,Enums,什么是java枚举?它们是如何工作的?我在哪里可以使用它们?如何使用? 我可以在应用程序中不使用枚举吗?或者它们功能强大,使用它们比忽略它们要好吗?Sun的可能是最好的解释。当然,在Java1.5发布之前,Java程序员当然可以不用它们。通常,在1.5之前的Java版本中使用常量也可以完成同样的任务。但是枚举非常方便。Java 5+中的枚举基本上是具有预定义实例集的类。它们是用来替代,比如说,整数常量集合的。它们最好使用常量,因为它们可以强制执行类型安全性 因此,不是: public class

什么是java枚举?它们是如何工作的?我在哪里可以使用它们?如何使用?

我可以在应用程序中不使用枚举吗?或者它们功能强大,使用它们比忽略它们要好吗?

Sun的可能是最好的解释。当然,在Java1.5发布之前,Java程序员当然可以不用它们。通常,在1.5之前的Java版本中使用常量也可以完成同样的任务。但是枚举非常方便。

Java 5+中的枚举基本上是具有预定义实例集的类。它们是用来替代,比如说,整数常量集合的。它们最好使用常量,因为它们可以强制执行类型安全性

因此,不是:

public class Suit {
  public final static int SPADES = 1;
  public final static int CLUBS = 2
  public final static int HEARTS = 3;
  public final static int DIAMONDS = 4;
}
你有:

public enum Suit {
  SPADES, CLUBS, HEARTS, DIAMONDS
}
优点是:

  • 类型安全。您可以将函数参数、返回类型、类成员或局部变量声明为特定的枚举类型,编译器将强制执行类型安全
  • 枚举基本上是类。它们可以实现接口、具有行为等等
  • 类型安全性是一个问题,因为在第一个示例中,这些是有效的语句:

    int i = Suit.DIAMONDS * Suit.CLUBS;
    
    或者你可以把11传递给一个需要一套西装的函数。使用类型安全枚举无法做到这一点

    您可以使用Suit类来提供类型安全性,这是Java5之前的解决方案。Josh Bloch(in,这是Java程序员imho的必读读物)推广了类型安全枚举模式,成为Java5+枚举。它有相当多的样板文件,还有一些人们不喜欢的极端情况,比如序列化,不调用构造函数,为了确保只得到一个实例,必须重写readResolve()方法

    例如:

    public enum CardColour {
      RED, BLACK
    }
    
    public enum Suit {
      SPADES(CardColour.BLACK),
      CLUBS(CardColour.BLACK),
      HEARTS(CardColour.RED),
      DIAMONDS(CardColour.RED);
    
      private final CardColour colour;
    
      Suit(CardColour colour) { this.colour = colour; }
    
      public CardColour getColour() { return colour; }
    }
    
    enum MultipleChoiceAnswer { A, B, C, D };
    
    编辑:太阳有一个

    至于接口,它们实际上是对枚举的补充,而不是替代。就像你可以说西装是一个界面,你会有:

    public interface Suit {
      CardColour getColour();
    }
    
    问题是,你可以去定义300种不同的西装,你也可以定义几次黑桃。enum的另一个优点是(尽管存在类加载角情况)每个enum值只有一个实例。通常,这被称为具有标准值,这意味着此等式成立:

    a.equals(b) == b.equals(a) == (a == b)
    
    对于作为特定枚举实例的所有a、b。这意味着,不要写:

    if (card.getSuit().equals(Suit.SPADES)) { ... }
    
    你可以写:

    if (card.getSuit() == Suit.SPADES) { ... }
    

    这是更快,通常更容易阅读。另外,如果您比较不同类型的枚举,说它们不可能相等,IDE通常会给您反馈,这可能是一种有用的早期错误检查形式。

    如果没有出现这种情况,您就不需要它们

    它们允许你有一个定义良好的事物集,例如,如果你想表示你可以拥有的物质状态:

    enum MatterState {
        Solid,
        Liquid,
        Gas;
    }
    
    他们以多种方式打破了使用对象表示集合的旧式风格,其中一些方式包括:

    • 您可以在交换机中使用它们 声明
    • 更少的代码
    • 内置 到/从字符串

    根据我的解释,枚举比其他任何东西更具可读性。它们基本上用于用更具描述性的名称来替换1-6等值,如[高兴、悲伤、愤怒等]
    每当需要使用一小组变量来描述所期望的解决方案时,您都应该使用它们。

    将Enum考虑如下

    public class MyEnum {
    
        // Object instantiated at declaration
        public static final MyEnum ONE = new MyEnum();
        public static final MyEnum TWO = new MyEnum();
        public static final MyEnum THREE = new MyEnum();
    
        // Notice a private constructor 
        // There is no way outside MyEnum class call it
        private MyEnum() { ... }
    
    
    }
    
    所以MyEnum作为枚举应该是

    public enum MyEnum {
        ONE,
        TWO,
        THREE;
    }
    
    两者相似


    关于,

    要添加更多信息以了解更多信息,最好从变量及其值的概念开始。正如我现在确信的那样,每个变量都有一个声明的类型(比如Java基元类型)。每种类型都有其相应的值。例如,char类型的变量可以接受所有单个字符作为其值。因此,当您想要声明一个变量可以接受所有字符常量集时,它非常有用。例如,所有字符常量对于aCharToStopProgram变量都是可接受且有意义的:

    char aCharToStopProgram = getUserInput();
    
    然而,当您有一个有限的值时,我的意思是变量的值域被限制为特殊值。例如,您有userChoice,它保留了系统多项选择题的值。所以只有“a”、“b”、“c”、“d”是有意义的。您不希望在程序代码的另一部分(或任何其他原因)为该变量指定无意义的值,例如“s”。现在我们的变量使用char基元类型,它可以接受任何字符常量,如下所示

    char userChoice = getUserChoice();
    
    在这种情况下,Java提供枚举类型。这意味着您可以通过enum关键字定义一个新类,该类具有有限的固定实例,即调用命名值(您不能创建新对象)。例如:

    public enum CardColour {
      RED, BLACK
    }
    
    public enum Suit {
      SPADES(CardColour.BLACK),
      CLUBS(CardColour.BLACK),
      HEARTS(CardColour.RED),
      DIAMONDS(CardColour.RED);
    
      private final CardColour colour;
    
      Suit(CardColour colour) { this.colour = colour; }
    
      public CardColour getColour() { return colour; }
    }
    
    enum MultipleChoiceAnswer { A, B, C, D };
    

    因此,您可以使用自己的类型定义变量:

    MultipleChoiceAnswer userChoice = getUserChoice();//OR MultipleChoiceAnswer.A      
    

    为什么它包含在Java1.5中?它有那么强大吗?《太阳指南》(Sun'sguide)很好地展示了它们的潜力;我建议添加一个参考资料供进一步阅读。@cletus。。。界面不能用于相同的用途吗?@cletus:我不理解其中的“类型安全”部分。Java类不提供类型安全吗?@Kevin:例如,与C#相反,不可能使用显式强制转换来“伪造”枚举(
    MyEnum e=(MyEnum)45;
    )@Kevin:@cletus正在比较枚举(typesafe)和“使用ints的模拟枚举”(非typesafe)。请再读一遍答案。@bogerton:事实上,使用Java枚举有显著的类型安全优势;请参阅@cletus的优秀答案。注意,默认情况下,java中的所有枚举都扩展了java.lang.Enum。因此,任何enum都不应扩展任何其他接口,而应实现任何数量的接口。这是因为java不允许多重继承。