理解 Java 中的枚举

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1419835/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 16:29:15  来源:igfitidea点击:

Understanding Enums in Java

javaenums

提问by Kevin Boyd

What are java enums? How do they work? Where could I used them and how?
Can I do without using enums in an app or are they so powerful that Its better to use them than ignore them?

什么是java枚举?它们是如何工作的?我可以在哪里使用它们以及如何使用它们?
我可以在应用程序中不使用枚举吗,或者它们是如此强大以至于使用它们比忽略它们更好?

回答by cletus

Enums in Java 5+ are basically classes that have a predefined set of instances. They are intended as a replacement for, say, a collection of integer constants. They are preferably to constants as they can enforce type safety.

Java 5+ 中的枚举基本上是具有一组预定义实例的类。它们旨在替代整数常量的集合。它们最好是常量,因为它们可以强制类型安全。

So instead of:

所以而不是:

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;
}

you have:

你有:

public enum Suit {
  SPADES, CLUBS, HEARTS, DIAMONDS
}

The advantages are:

优点是:

  1. Type safety. You can declare a function argument, return type, class member or local variable to be a particular Enum type and the compiler will enforce type safety;
  2. Enums are basically classes. They can implement interfaces, have behaviour and so on.
  1. 类型安全。您可以将函数参数、返回类型、类成员或局部变量声明为特定的 Enum 类型,编译器将强制执行类型安全;
  2. 枚举基本上是类。他们可以实现接口,拥有行为等等。

The type safety is an issue because in the first example, these are valid statements:

类型安全是一个问题,因为在第一个示例中,这些是有效的语句:

int i = Suit.DIAMONDS * Suit.CLUBS;

or you can pass in 11 to a function expecting a suit. You can't do that with a typesafe enum.

或者您可以将 11 传递给需要西装的函数。你不能用类型安全的枚举来做到这一点。

You can use a class for Suit to provide type safety and this was the solution before Java 5. Josh Bloch (in Effective Java, which is a must readfor Java programmers imho) promoted the typesafe enum pattern that became the Java 5+ enum. It has a fair amount of boilerplate on it and some corner cases that people didn't tend to cater for, such as serialization not calling a constructor and to ensure you only got one instance you had to override the readResolve() method.

您可以使用 Suit 的类来提供类型安全,这是 Java 5 之前的解决方案。 Josh Bloch(在Effective Java 中,恕我直言,这是Java 程序员的必读之物)促进了成为 Java 5+ 枚举的类型安全枚举模式。它有相当多的样板文件和一些人们不倾向于满足的极端情况,例如序列化不调用构造函数并确保您只有一个实例,您必须覆盖 readResolve() 方法。

For example:

例如:

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; }
}

Edit:Sun has an introduction to typesafe enums.

编辑:Sun介绍了 typesafe enums

As for interfaces, they really complement enums rather than being an alternative. Like you could say that Suit is an interface and you'd have this:

至于接口,它们确实是对枚举的补充而不是替代。就像您可以说 Suit 是一个界面一样,您将拥有以下内容:

public interface Suit {
  CardColour getColour();
}

The problem is that you could go and define 300 different suits and you could also define Spades several times. Another advantage of enums is (classloading corner cases notwithstanding) is that there is only one instance of each enum value. Typically this is referred to as having a canonical value, meaning this equality holds true:

问题是您可以定义 300 种不同的花色,也可以多次定义黑桃。枚举的另一个优点是(尽管有类加载的极端情况)是每个枚举值只有一个实例。通常,这被称为具有规范值,这意味着此等式成立:

a.equals(b) == b.equals(a) == (a == b)

for all a, b that are instances of a particular Enum. This means that instead of writing:

对于所有 a, b 是特定 Enum 的实例。这意味着,而不是写:

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

you can write:

你可以写:

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

which is quicker and typically easier to read. Plus IDEs will typically give you feedback if you're comparing enums of different types saying they can't possibly be equal, which can be a useful and early form of error-checking.

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

回答by Arthur Ronald

Think of Enum as follows

将 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() { ... }


}

So a MyEnum as a enum would be

因此,作为枚举的 MyEnum 将是

public enum MyEnum {
    ONE,
    TWO,
    THREE;
}

Both are similar

两者都相似

regards,

问候,

回答by Asaph

Sun's enum documentationis probably the best explanation. Of course you can do without them as Java programmers certainly did until Java 1.5 was released. You would typically accomplish the same thing by using constants in versions of Java before 1.5. But enums are a nice convenience.

Sun 的枚举文档可能是最好的解释。当然,您可以不用它们,就像 Java 程序员在 Java 1.5 发布之前所做的那样。您通常会通过在 1.5 之前的 Java 版本中使用常量来完成相同的事情。但枚举是一个很好的便利。

回答by Tom

If the situation doesn't come up then you don't need them.

如果情况没有出现,那么您就不需要它们。

They allow you to have a well defined set of things, for instance if you wanted to represent the states of matter you could have:

它们允许您拥有一组明确定义的事物,例如,如果您想表示您可以拥有的物质状态:

enum MatterState {
    Solid,
    Liquid,
    Gas;
}

Where they beat the old style of using objects to represent sets in a number of ways, some of which are:

他们击败了使用对象以多种方式表示集合的旧风格,其中一些是:

  • You can use them in switch statements.
  • Less code.
  • Built in to/from string.
  • 您可以在 switch 语句中使用它们。
  • 更少的代码。
  • 内置于/来自字符串。

回答by MMKarami

To add some additional information to find out it more, it is better to start with concept of a variable and its values. As I am sure you now, each variable has a declared type (such as Java primitive types). Each type has its own corresponding values. For example a variables with the char type can accept all individual characters as its values. So it is very helpful when you want to declare a variable can accept all set of character constants. For instance all character constants are acceptable and meaningful for aCharToStopProgram variable:

要添加一些附加信息以了解更多信息,最好从变量及其值的概念开始。正如我现在确定的那样,每个变量都有一个声明的类型(例如 Java 原始类型)。每种类型都有其对应的值。例如,char 类型的变量可以接受所有单个字符作为其值。所以当你想声明一个变量可以接受所有字符常量集时是非常有帮助的。例如,对于 CharToStopProgram 变量,所有字符常量都是可接受且有意义的:

char aCharToStopProgram = getUserInput();

However, what about when you have a limited value, I mean value's domain of your variable is restricted to special values. For example you have userChoice which keeps value of system multiple choice question. So just 'a', 'b', 'c', 'd' is meaningful. You don't want in another section of your program code(or any other reason) this variable is assigned with meaningless values such as 's'. Now is it true to use a char primitive type for our variable which can accept any character constant, such following.

但是,当您的值有限时,我的意思是变量的值域仅限于特殊值。例如,您有 userChoice,它保留系统多项选择问题的价值。所以只有 'a', 'b', 'c', 'd' 是有意义的。您不希望在程序代码的另一部分(或任何其他原因)为该变量分配无意义的值,例如“s”。现在对我们的变量使用 char 原始类型是否正确,它可以接受任何字符常量,如下所示。

char userChoice = getUserChoice();

In this situations Java provides Enumerated Types. It means via enum keyword you can define a new class that has limited and fixed instances which is call named values(you can not creat new objects). For example:

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

enum MultipleChoiceAnswer { A, B, C, D };

or

或者

public enum MultipleChoiceAnswer {

    A('a'), B('b'), C('c'), D('d');

    private char choice;

    private MultipleChoiceAnswer(char choice) { 
        this.choice = choice; 
    }

    public String getChoice() { 
        return choice; 
    }
}

As result you can define a variable with your own type:

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

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

回答by bogertron

From my interpretation, enums are more for readability than anything else. They are basically used to replace values like 1-6 with more descriptive names, like [Happy, Sad, Angry, etc] You should use them whenever you need to use a small set of variables to describe the solution that you are expecting.

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