Java基础14-深入理解Java枚举类(一):https://developer.aliyun.com/article/1535688
枚举类实战
实战一无参
(1)定义一个无参枚举类
enum SeasonType { SPRING, SUMMER, AUTUMN, WINTER } 复制代码
(2)实战中的使用
// 根据实际情况选择下面的用法即可 SeasonType springType = SeasonType.SPRING; // 输出 SPRING String springString = SeasonType.SPRING.toString(); // 输出 SPRING 复制代码
实战二有一参
(1)定义只有一个参数的枚举类
enum SeasonType { // 通过构造函数传递参数并创建实例 SPRING("spring"), SUMMER("summer"), AUTUMN("autumn"), WINTER("winter"); // 定义实例对应的参数 private String msg; // 必写:通过此构造器给枚举值创建实例 SeasonType(String msg) { this.msg = msg; } // 通过此方法可以获取到对应实例的参数值 public String getMsg() { return msg; } } 复制代码
(2)实战中的使用
// 当我们为某个实例类赋值的时候可使用如下方式 String msg = SeasonType.SPRING.getMsg(); // 输出 spring 复制代码
实战三有两参
(1)定义有两个参数的枚举类
public enum Season { // 通过构造函数传递参数并创建实例 SPRING(1, "spring"), SUMMER(2, "summer"), AUTUMN(3, "autumn"), WINTER(4, "winter"); // 定义实例对应的参数 private Integer key; private String msg; // 必写:通过此构造器给枚举值创建实例 Season(Integer key, String msg) { this.key = key; this.msg = msg; } // 很多情况,我们可能从前端拿到的值是枚举类的 key ,然后就可以通过以下静态方法获取到对应枚举值 public static Season valueofKey(Integer key) { for (Season season : Season.values()) { if (season.key.equals(key)) { return season; } } throw new IllegalArgumentException("No element matches " + key); } // 通过此方法可以获取到对应实例的 key 值 public Integer getKey() { return key; } // 通过此方法可以获取到对应实例的 msg 值 public String getMsg() { return msg; } } 复制代码
(2)实战中的使用
// 输出 key 为 1 的枚举值实例 Season season = Season.valueofKey(1); // 输出 SPRING 实例对应的 key Integer key = Season.SPRING.getKey(); // 输出 SPRING 实例对应的 msg String msg = Season.SPRING.getMsg(); 复制代码
枚举类总结
其实枚举类懂了其概念后,枚举就变得相当简单了,随手就可以写一个枚举类出来。所以如上几个实战小例子一定要先搞清楚概念,然后在练习几遍就 ok 了。
重要的概念,我在这里在赘述一遍,帮助老铁们快速掌握这块知识,首先记住,枚举类中的枚举值可以没有参数,也可以有多个参数,每一个枚举值都是一个实例;
并且还有一点很重要,就是如果枚举值有 n 个参数,那么构造函数中的参数值肯定有 n 个,因为声明的每一个枚举值都会调用构造函数去创建实例,所以参数一定是一一对应的;既然明白了这一点,那么我们只需要在枚举类中把这 n 个参数定义为 n 个成员变量,然后提供对应的 get() 方法,之后通过实例就可以随意的获取实例中的任意参数值了。
如果想让枚举类更加的好用,就可以模仿我在实战三中的写法那样,通过某一个参数值,比如 key 参数值,就能获取到其对应的枚举值,然后想要什么值,就 get 什么值就好了。
枚举 API
我们使用 enum 定义的枚举类都是继承 java.lang.Enum 类的,那么就会继承其 API ,常用的 API 如下:
- String name()
获取枚举名称
- int ordinal()
获取枚举的位置(下标,初始值为 0 )
- valueof(String msg)
通过 msg 获取其对应的枚举类型。(比如实战二中的枚举类或其它枚举类都行,只要使用得当都可以使用此方法)
- values()
获取枚举类中的所有枚举值(比如在实战三中就使用到了)
总结
枚举本质上是通过普通的类来实现的,只是编译器为我们进行了处理。每个枚举类型都继承自java.lang.Enum,并自动添加了values和valueOf方法。
而每个枚举常量是一个静态常量字段,使用内部类实现,该内部类继承了枚举类。所有枚举常量都通过静态代码块来进行初始化,即在类加载期间就初始化。
另外通过把clone、readObject、writeObject这三个方法定义为final的,同时实现是抛出相应的异常。这样保证了每个枚举类型及枚举常量都是不可变的。可以利用枚举的这两个特性来实现线程安全的单例