栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

枚举:为什么?什么时候?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

枚举:为什么?什么时候?

这些是主要的论点

enum
EnumMap
以及
EnumSet
短的例子。

的情况
enum

从Java
6开始,

java.util.Calendar
是一个凌乱类的示例,该类可以从使用中受益匪浅
enum
(除其他改进外)。

当前

Calendar
定义以下常量(以及许多其他常量):

// int constant antipattern from java.util.Calendarpublic static final int JANUARY = 0;public static final int FEBRUARY = 1;...public static final int SUNDAY = 1;public static final int MonDAY = 2;...

这些都是

int
,尽管它们显然代表了不同的概念实体。

以下是一些严重的后果:

  • 它很脆 ;在需要时必须小心分配不同的编号。
    • 如果错误我们设置
      MonDAY = 0;
      SUNDAY = 0;
      ,则有
      MonDAY == SUNDAY
  • 没有名称空间,也没有类型安全性 ,因为一切都只是一个
    int
    • 我们可以
      setMonth(JANUARY)
      ,但我们也可以
      setMonth(THURSDAY)
      setMonth(42)
    • 谁知道
      set(int,int,int,int,int,int)
      (一种真正的方法!)做什么!

相比之下,我们可以有类似以下内容:

// Hypothetical enums for a Calendar libraryenum Month {   JANUARY, FEBRUARY, ...}enum DayOfWeek {   SUNDAY, MONDAY, ...}

现在我们不必担心

MonDAY ==SUNDAY
(它永远不会发生!),并且由于
Month
DayOfWeek
是不同的类型,因此
setMonth(MONDAY)
不会编译。

此外,以下是一些前后代码:

// BEFORE with int constantsfor (int month = JANUARY; month <= DECEMBER; month++) {   ...}

在这里,我们进行各种假设,例如

JANUARY + 1 ==FEBRUARY
等等。另一方面,
enum
对应项更加简洁,可读性强,并且做出的假设更少(因此,发生错误的机会也更少):

// AFTER with enumfor (Month month : Month.values()) {   ...}

实例字段的情况

在Java中,

enum
是一个
class
具有许多特殊的性质,但
class
尽管如此,允许您根据需要来定义实例方法和字段。

考虑以下示例:

// BEFORE: with int constantspublic static final int NORTH = 0;public static final int EAST  = 1;public static final int SOUTH = 2;public static final int WEST  = 3;public static int degreeFor(int direction) {   return direction * 90; // quite an assumption!   // must be kept in-sync with the int constants!}//...for (int dir = NORTH; dir <= WEST; dir++) {   ... degreeFor(dir) ...}

另一方面,

enum
您可以这样写:

enum Direction {   NORTH(0), EAST(90), SOUTH(180), WEST(270);   // so obvious! so easy to read! so easy to write! so easy to maintain!   private final int degree;   Direction(int degree)      { this.degree = degree; }   public int getDegree()     { return degree; }}//...for (Direction dir : Direction.values()) {   ... dir.getDegree() ...}

实例方法的情况

考虑以下示例:

static int apply(int op1, int op2, int operator) {   switch (operator) {      case PLUS  : return op1 + op2;      case MINUS : return op1 - op2;      case ...      default: throw new IllegalArgumentException("Unknown operator!");   }}

如前面的示例所示,

enum
在Java中可以有实例方法,但不仅如此,每个常量也可以有自己的特定
@Override
方法。如下代码所示:

enum Operator {    PLUS  { int apply(int op1, int op2) { return op1 + op2; } },    MINUS { int apply(int op1, int op2) { return op1 - op2; } },    ...    ;    abstract int apply(int op1, int op2);}

的情况
EnumMap

这是来自 Effective Java 2nd Edition 的引用:

从未导出与一个相关联的值

enum
从其
ordinal()
;
而是将其存储在实例字段中。( 第31项:使用实例字段代替序数
)使用序数为数组建立索引很少是合适的:使用
EnumMap
替代。一般原则是,应用程序程序员应该很少使用(如果有的话)
Enum.ordinal
。(
项目33:使用
EnumMap
而不是顺序索引


从本质上讲,您可能会像这样:

// BEFORE, with int constants and array indexingEmployee[] employeeOfTheMonth = ...employeeOfTheMonth[JANUARY] = jamesBond;

现在您可以拥有:

// AFTER, with enum and EnumMapMap<Month, Employee> employeeOfTheMonth = ...employeeOfTheMonth.put(Month.JANUARY, jamesBond);

的情况
EnumSet

int
例如,在C
++中经常使用两个常数的幂来表示位集。这依赖于按位运算。一个例子可能看起来像这样:

public static final int BUTTON_A = 1;public static final int BUTTON_B = 2;public static final int BUTTON_X = 4;public static final int BUTTON_Y = 8;int buttonState = BUTTON_A | BUTTON_X; // A & X are pressed!if ((buttonState & BUTTON_B) != 0) {   // B is pressed...   ...}

使用

enum
EnumSet
,可以看起来像这样:

enum Button {  A, B, X, Y;}Set<Button> buttonState = EnumSet.of(Button.A, Button.X); // A & X are pressed!if (buttonState.contains(Button.B)) { // B is pressed...   ...}

参考文献

  • Java语言指南/枚举 -包含许多示例的相当完整的介绍

也可以看看

  • 有效的Java 2nd Edition
    • 条款30:使用
      enum
      而不是
      int
      常量
    • 第31项:使用实例字段代替普通字段
    • 项目32:使用
      EnumSet
      代替位字段
    • 项目33:使用
      EnumMap
      而不是顺序索引


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/413894.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号