• [10] 枚举



    1、枚举类的定义和意义

    1.1 基本概念

    枚举类型(Enumerated Type) 用来将一组类似的值包含到一种类型当中。而这种枚举类型的名称则会被定义成独一无二的类型描述符。

    枚举类型的出现有什么意义?为什么不可以用普通的常量直接定义来替代呢?我们先看一个示例,假如现在希望为彩虹描述出七种颜色,在Java中通过常量定义的方式来实现:
     Public static class RainbowColor {  
        
        // 红橙黄绿青蓝紫七种颜色的常量定义
        public static final int RED = 0; 
        public static final int ORANGE = 1; 
        public static final int YELLOW = 2; 
        public static final int GREEN = 3; 
        public static final int CYAN = 4; 
        public static final int BLUE = 5; 
        public static final int PURPLE = 6; 
     }

    然后在程序中,你可以直接引用这些常量。那么问题来了:
    • 类型不安全
    • 由于颜色常量的对应值是整数形,所以程序执行过程中很有可能给颜色变量传入一个任意的整数值,导致出现错误。

    • 没有命名空间
    • 由于颜色常量只是类的属性,当你使用的时候不得不通过类来访问。

    • 类型无指意性
    • 由于颜色常量值仅仅是一些无任何含义的整数值,如果在运行期调试时候,你就会发现日志中有很多魔术数字,但除了程序员本身,其他人很难明白其奥秘。

    1.2 如何定义一个Enum类

    如上提到的彩虹色,你用枚举类可以这样做:
    enum RainbowColor { RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, PURPLE }

    创建枚举类型要使用 enum 关键字,它本质上是一个类,其隐含的父类是java.lang.Enum(java.lang.Enum 是一个抽象类)。所以自动继承了Enum的一些方法。

    枚举类型符合通用模式 Class Enum<E extends Enum<E>>,而 E 表示枚举类型的名称。

    枚举类型的每一个值都将映射到 protected Enum(String name, int ordinal) 构造函数中,在这里,每个值的名称都被转换成一个字符串,并且序数设置表示了此设置被创建的顺序

    上面这些话的意思在于,假如有枚举类:
    public enum Weekday {
        MON, TUE, WED, THU, FRI, SAT, SUN;
    }

    实际上这段代码调用了7次 Enum(String name, int ordinal):
    new Enum<Weekday>("MON",0);
    new Enum<Weekday>("TUE",1);
    new Enum<Weekday>("WED",2);
    ...

    取用的时候是这样:
    Weekday wd = Weekday.MON;

    枚举定义尽量以Enum结尾方便识别,如下的 WeekEnum
    但枚举的基本使用,我们只能创建名称,例如星期,希望能有对应的值,怎么处理?枚举毕竟是一个类,所以完全可以这样:
    // 定义一个星期的枚举类
    public enum WeekEnum {
    
     // 因为已经定义了带参数的构造器,所以在列出枚举值时必须传入对应的参数
     SUNDAY("星期日"), MONDAY("星期一"), TUESDAY("星期二"), WEDNESDAY("星期三"), 
     THURSDAY("星期四"), FRIDAY("星期五"), SATURDAY("星期六");
    
     // 定义一个 private 修饰的实例变量
     private String value;
    
     // 定义一个带参数的构造器,枚举类的构造器只能使用 private 修饰
     private WeekEnum(String value) {
         this.value = value;
     }
    
     // 定义 get set 方法
     public String getValue() {
         return value;
     }
    
     public void setValue(String value) {
         this.value = value;
     }
    
    }

    1.3 Enum的好处

    • 枚举类(对象)可以直接用于switch语句(实际上的原理是,Java编译器会自动在枚举成员上调用ordinal()方法)
    • 作为类,它可以自定义属性和方法
    • 有EnumMap和EnumSet两个工具类,同时也是Map和Set接口的实现类,详见 Java 语言中 Enum 类型的使用介绍



    2、如何避免错误地使用Enum

    (1)enum 类型不支持 public 和 protected 修饰符的构造方法,因此构造函数一定要是 private 的。也正因为如此,所以枚举对象是无法在程序中通过直接调用其构造方法来初始化的。

    (2)定义 enum 类型时候,如果是简单类型,那么最后一个枚举值后不用跟任何一个符号;但如果有定制方法,那么最后一个枚举值与后面代码要用分号';'隔开,不能用逗号或空格。

    (3)由于 enum 类型的值实际上是通过运行期构造出对象来表示的,因而在做比较操作时候就需要注意,如果直接通过使用等号 ( ‘ == ’ ) 操作符,这些看似一样的枚举值一定不相等,因为这不是同一个对象实例。



    3、枚举的常用方法

    • ordinal(),返回成员的声明顺序编号,初始为0,类似数组的索引
    • name(),返回枚举成员的名称
    • toString(),返回枚举常量的名称,和name()类似
    • values(),常用来遍历,返回枚举类的数组(values()是由编译器添加的static方法)



    4、参考链接



  • 相关阅读:
    映射和分析
    文档操作
    向 Nginx 主进程发送 USR1 信号
    ES集群7.3.0设置快照,存储库进行索引备份和恢复等
    ES7.3.0配置邮件告警
    Elasticsearch 史上最全最常用工具清单
    Grok在线调试网址
    Linux 小知识翻译
    Linux 小知识翻译
    Linux 小知识翻译
  • 原文地址:https://www.cnblogs.com/deng-cc/p/7461846.html
Copyright © 2020-2023  润新知