Java 枚举 enum 详解

枚举类型

Java5 中添加了一个 enum 关键字,通过 enum 关键字,我们可以将一组拥有具名的值的有限集合创建为一种新的类型,这些具名的值可以作为常规的程序组件使用,例如:

public enum Spiciness {
    NOT, MILD, MEDIUM, HOT, FLAMING
}

复制代码

这里创建了一个名为 Spiciness 的枚举类型,它有 5 个值。由于枚举类型的实例是常量,因此按照命名惯例,它们都用大写字母表示(如果名称中含有多个单词,使用下划线分隔)

要使用 enum,需要创建一个该类型的引用,然后将其赋值给某个实例:

public class SimpleEnumUse {
    public static void main(String[] args) {
        Spiciness howHot = Spiciness.MEDIUM;
        System.out.println(howHot);
    }
}
// 输出:MEDIUM
复制代码

在 switch 中使用 enum,是 enum 提供的一项非常便利的功能。一般来说,在 switch 中只能使用整数值,而枚举实例天生就具备整数值的次序,并且可以通过 ordinal() 方法取得其次序,因此我们可以在 switch 语句中使用 enum

一般情况下我们必须使用 enum 类型来修饰一个 enum 实例,但是在 case 语句中却不必如此。下面的例子使用 enum 构造了一个模拟红绿灯状态变化:

enum Signal { GREEN, YELLOW, RED, }

public class TrafficLight {
    
    Signal color = Signal.RED;
    
    public void change() {
        switch(color) {
            case RED: color = Signal.GREEN;
                break;
            case GREEN: color = Signal.YELLOW;
                break;
            case YELLOW: color = Signal.RED;
                break;
        }
    }
    
    @Override
    public String toString() {
        return "The traffic light is " + color;
    }
    
    public static void main(String[] args) {
        TrafficLight t = new TrafficLight();
        for(int i = 0; i < 7; i++) {
            System.out.println(t);
            t.change();
        }
    }
}
复制代码

枚举的基本特性

Java 中的每一个枚举都继承自 java.lang.Enum 类,所有枚举实例都可以调用 Enum 类的方法

调用 enum 的 values() 方法,返回 enum 实例的数组,而且该数组中的元素严格保持其在 enum 中声明时的顺序,因此你可以在循环中使用 values() 返回的数组

enum Shrubbery { GROUND, CRAWLING, HANGING }
public class EnumClass {
    public static void main(String[] args) {
        for(Shrubbery s : Shrubbery.values()) {
            System.out.println(s);
            // 返回每个枚举实例在声明时的次序
            System.out.println(s.ordinal());
            // 返回与此枚举常量的枚举类型相对应的 Class 对象
            System.out.println(s.getDeclaringClass());
            // 返回枚举实例声明时的名字,效果等同于直接打印
            System.out.println(s.name());
            ...
        }
    }
}
// 输出:
// GROUND
// 0
// GROUND
// CRAWLING
// 1
// CRAWLING
// HANGING
// 2
// HANGING
复制代码

可以使用 == 来比较 enum 实例,编译器会自动为你提供 equals() 和 hashCode() 方法。同时,Enum 类实现了 Comparable 接口,所以它具有 compareTo() 方法,同时,它还实现了 Serializable 接口

ValueOf() 方法是在 Enum 中定义的 static 方法,根据给定的名字返回相应的 enum 实例,如果不存在给定名字的实例,将抛出异常

Shrubbery shrub = Enum.valueOf(Shrubbery.class, "HANGING");
复制代码

我们再来看看 values() 方法,为什么要说这个呢?前面提到,编译器为你创建的 enum 类都继承自 Enum 类。然而,如果你研究一下 Enum 类就会发现,它并没有 values() 方法。可我们明明已经用过该方法了呀,难道是这个方法被藏起来了?答案是,values() 是由编译器添加的 static 方法,编译器还会为创建的枚举类标记为 static final,所以无法被继承

由于 values() 方法是由编译器插入到 enum 定义中的 static 方法,所以,如果你将 enum 实例向上转型为 Enum,那么 values() 方法就不可用了。不过,在 Class 中有一个 getEnumConstants() 方法,所以即便 Enum 接口中没有 values() 方法,我们仍然可以通过 Class 对象取得所有 enum 实例

enum Search { HITHER, YON }
public class UpcastEnum {
    public static void main(String[] args) {
        for(Enum en : e.getClass().getEnumConstants())
            System.out.println(en);
    }
}
复制代码

因为 getEnumConstants() 是 Class 上的方法,所以你甚至可以对不是枚举的类调用此方法,只不过,此时该方法返回 null

方法添加

除了不能继承自一个 enum 之外,我们基本上可以将 enum 看作一个常规的类。也就是说我们可以向 enum 中添加方法。enum 甚至可以有 main() 方法

我们希望每个枚举实例能够返回对自身的描述,而不仅仅只是默认的 toString() 实现,这只能返回枚举实例的名字。为此,你可以提供一个构造器,专门负责处理这个额外的信息,然后添加一个方法,返回这个描述信息。看一看下面的示例:

public enum OzWitch {
    
    WEST("Miss Gulch, aka the Wicked Witch of the West"),
    NORTH("Glinda, the Good Witch of the North"),
    EAST("Wicked Witch of the East, wearer of the Ruby "),
    SOUTH("Good by inference, but missing");	// 必须在 enum 实例序列的最后添加一个分号
    
    private String description;
    
    private OzWitch(String description) {
        this.description = description;
    }
    
    public St
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值