了解 Java 中的枚举

2022-09-02 00:02:59

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


答案 1

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
}

其优点是:

  1. 类型安全。您可以将函数参数,返回类型,类成员或局部变量声明为特定的Enum类型,编译器将强制实施类型安全;
  2. 枚举基本上是类。它们可以实现接口,具有行为等。

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

int i = Suit.DIAMONDS * Suit.CLUBS;

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

您可以使用 Suit 的类来提供类型安全,这是 Java 5 之前的解决方案。Josh Bloch(在 Effective Java 中,恕我直言,这是 Java 程序员必读的)推广了成为 Java 5+ 枚举的 typesafe 枚举模式。它上面有相当多的样板和一些人们不倾向于满足的角落情况,例如序列化不调用构造函数,并且为了确保你只有一个实例,你必须重写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; }
}

编辑:Sun 介绍了类型安全枚举

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

public interface Suit {
  CardColour getColour();
}

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

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

对于所有 a、b,它们都是特定枚举的实例。这意味着不要写:

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

你可以写:

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

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


答案 2

将枚举视为如下所示

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

两者相似

问候