了解Java中的枚举 [英] Understanding Enums in Java

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

问题描述

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

我可以不在应用程序中使用枚举,还是使用它们非常强大,以免使用它们而不是忽略它们?

解决方案

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



所以而不是:

 code> 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. 输入安全性。您可以声明函数参数,返回类型,类成员或局部变量为特定的枚举类型,编译器将强制执行类型安全性;

  2. 枚举基本上是类。他们可以实现接口,有行为等。

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

  int i = Suit.DIAMONDS * Suit.CLUBS; 

或者你可以将11传递给一个期待着西装的功能。您不能使用类型安全的枚举来执行此操作。



您可以使用Suit来提供类型安全性,这是Java 5之前的解决方案。Josh Bloch(in 有效的Java ,这是Java程序员imho必须阅读),促进了类型安全枚举模式,成为Java 5+枚举。它有一个相当大的样板和一些人们不喜欢的角色,例如序列化不调用构造函数,并确保只有一个实例你必须覆盖readResolve()方法。 p>

例如:

  public enum CardColour {
RED, BLACK
}

public enum Suit {
SPADES(CardColour.BLACK),
CLUBS(CardColour.BLACK),
HEARTS(CardColour.RED) ,
DIAMONDS(CardColour.RED);

私人终端CardColour颜色;

西装(CardColour颜色){this.colour = color; }

public CardColour getColour(){return color;
}

编辑:Sun有一个 typesafe枚举的介绍



对于接口,他们真的补充枚举而不是替代。就像你可以说,西装是一个接口,你会有这样的:

  public interface Suit {
CardColour getColour ();
}

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

  a。等于(b)== b.equals(a)==(a == b)

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

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

你可以写:

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

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


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?

解决方案

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.

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.

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.

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 read for 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.

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.

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:

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:

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:

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.

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

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