添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

枚举是一个非常古老的语言特性,用来实现具名的有限集合,在 C/C++ 中使用广泛。而 Java 在 Java SE5 才引入枚举。也许语言设计者觉得既然是后引入该特性,那么一定要在这个特性上支持比其他语言更多的特性。这些特性的确让 Java 的枚举功能看起来更加“成熟”,同时也引入了一些复杂性,需要开发者关注。

枚举是一个不能继承的常规类

定义一个一周七天的枚举类型:

╰─➤ javap EnumWeekDay Compiled from "EnumWeekDay.java" public final class EnumWeekDay extends java.lang.Enum<enumweekday> { public static final EnumWeekDay Mon; public static final EnumWeekDay Tue; public static final EnumWeekDay Wed; public static final EnumWeekDay Thu; public static final EnumWeekDay Fri; public static final EnumWeekDay Sat; public static final EnumWeekDay Sun; public static EnumWeekDay[] values(); public static EnumWeekDay valueOf(java.lang.String); static {}; }</enumweekday>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
╰─➤ javap EnumWeekDay
Compiled from "EnumWeekDay.java"
public final class EnumWeekDay extends java . lang . Enum & lt ; enumweekday & gt ; {
public static final EnumWeekDay Mon ;
public static final EnumWeekDay Tue ;
public static final EnumWeekDay Wed ;
public static final EnumWeekDay Thu ;
public static final EnumWeekDay Fri ;
public static final EnumWeekDay Sat ;
public static final EnumWeekDay Sun ;
public static EnumWeekDay [ ] values ( ) ;
public static EnumWeekDay valueOf ( java . lang . String ) ;
static { } ;
} & lt ; / enumweekday & gt ;
  • 枚举类型的关键字 enum 其实只是一个语法糖,编译器最终把它转化为一个final类,因此枚举是不可继承的。
  • 枚举类型都继承自 java.lang.Enum 类。
  • 枚举的每一个取值被编译器传化为了一个个 static final 属性。
  • 本质上,这就是一个普通类,因此你可以在枚举是添加各种方法,甚至是main方法。
  • 神奇的 values() 方法

    从上面我们可以看出枚举类型被添加了一个静态的 values() 方法,但是 java.lang.Enum 并没有该方法。其实,这个方法是编译器添加的。通过这个方法可以获取到该枚举类型的所有取值。这个方法在需要遍历枚举取值,进行判断筛选的场景非常有用,可参考下例的 getByZhName 方法。

    在枚举中保存其他信息

    在 C 中,枚举可以简单的理解为具名的整型子集。Java 扩展了这个属性,使得可以在枚举中保存其他信息。

    定义一个水果枚举类,并包含中文信息:

    EnumFruit(String zhName) { System.out.println("enum init:" + zhName); this.zhName = zhName; * Getter method for property <tt>zhName</tt>. * @return property value of zhName public String getZhName() { return zhName; public EnumFruit getByZhName(String zhName) { for (EnumFruit fruit : values()) { if (fruit.getZhName().equals(zhName)) { return fruit; return null;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public enum EnumFruit {
    APPLE ( "苹果" ) ,
    BANANA ( "香蕉" ) ,
    ORANGE ( "橘子" ) ;
    private String zhName ;
    EnumFruit ( String zhName ) {
    System . out . println ( "enum init:" + zhName ) ;
    this . zhName = zhName ;
    }
    /**
    * Getter method for property <tt>zhName</tt>.
    *
    * @return property value of zhName
    */
    public String getZhName ( ) {
    return zhName ;
    }
    public EnumFruit getByZhName ( String zhName ) {
    for ( EnumFruit fruit : values ( ) ) {
    if ( fruit . getZhName ( ) . equals ( zhName ) ) {
    return fruit ;
    }
    }
    return null ;
    }
    }
    public class EnumUser { public static void main(String[] args) { EnumFruit fruit = EnumFruit.APPLE; System.out.println(fruit);

    使用 EnumSet 和 EnumMap 提供性能

    如果要在把枚举使用在 Set、Map 等集合场景,请使用 EnumSet EnumMap 。 EnumSet 使用了 bit vector 来标记元素,EnumMap 内部将 Map 实现简化为了数组,因此可以获得更好的性能。

    Java 的枚举语言特性作为一个后来者,的确带来了更加“成熟”和“丰富”的实现。但是,这些丰富的特性是否一定要在日常的项目中使用,我个人是不推荐的。就我个人理解,枚举最大的优点是类型和有限集合的约束,从而增强代码的一致性。因此,我提倡在项目代码中用 C 的枚举风格来使用 Java 枚举。此外,枚举并不是编程语言必须支持的特性,比如近段时间如日中天的 Golang 是不支持枚举的。既然是一个可有可无的语言特性,那就 use is as simple as possible 吧。

    Java 语言中 Enum 类型的使用介绍
    Java中的枚举与values()方法

    –EOF–

    版权声明
    转载请注明出处, 本文原始链接
    此条目由 daniel 发表在 Design Pattern Java 分类目录,并贴了 标签。将 固定链接 加入收藏夹。