关于Java 中Enum 的全方位剖析
来源:互联网 发布:java的前景怎么样 编辑:程序博客网 时间:2024/06/09 21:25
如果你受够了如下这种写法,那么这篇文章正好适合你:
setWeek(1);// ...private static final int MONDAY = 1;private static final int TUESDAY = 2;// ... setWeek(MONDAY);
这种方法有如下几个缺点:
- 不会进行安全检查,也就是说当传递的参数是100,它也不会报出编译错误;
- 可读性较差,类似setWeek(1)这种magic number,真是让人抓狂;
1. Enum的基本原理
针对这个问题Java
提供了解决办法,通过Enum
类型来完成,初次看到这个类型可能会有一点疑惑究竟是什么东西,和普通的类有什么不同,为了解决这个疑惑,我们首先弄清楚其中的原理,如下很简单常见枚举类型:
public enum Person{ MALE, FEMALE}
在编译之后使用JDK
自带的javap工具进行反编译查看字节码文件,如下:
从字节码文件中看可以得到一下信息:
Enum
类型Person
实际上是继承自java.lang.Enum<Person>
的类,所以不能再继承别的类,但是可以实现接口;- 由于类被
final
修饰,所以不能再被别的类继承; - 每个枚举常量都是该类的一个实例,并且被
public static final
修饰; - 该类有两个隐式静态的方法
values()
和valueOf()
; - 还有一个静态代码段
static{}
;
从上可以看出Enum其实就是通过公有静态的字段来达到和private static final int MONDAY = 1
相同的效果。
更进一步去查看反编译生成的字节码java -p Person.class,如下:
从上面的字节码可以看出其实Enum的实现并不复杂,只是被JDK
封装的很复杂。
2. 基本使用方法
2.1 两个有用的方法
由于Enum
枚举类型是继承自java.lang.Enum<Person>
的类,所以java.lang.Enum<Person>
其中的方法也可以被使用:
- name():返回枚举常量的名称;
- ordinal():返回枚举常量在枚举声明中的位置序号,第一个常量的位置是0;
但是这里有一个问题需要说一下,不要通过枚举的序号来唯一标识一个枚举常量,因为如果顺序改变,同一个枚举常量的序号就会变化,而最好采用一个字段来和枚举常量建立联系,如下这种写法是推荐的:
public enum Person{ MALE("M"), FEMALE("F"); private String value; Person(String value){ this.value = value; } public String getValue(){ return this.value; }}
注意
Enum
中的构造函数不能使用public
修饰,这也暗示我们枚举类型不推荐在外部实例化
另外对于name()
方法,JDK
也不建议我们直接使用,而是通过toString()方法返回可读性性更强的name。
2.2 用于switch
一般来说在使用switch的时候第一反应是使用int
类型进行判断,但是Enum出现之后也得到了switch支持,具体使用方法如下:
public class Main{ public static void main(String[] args) { Person person = Person.MALE; switch (person){ case MALE: System.out.println("male"); break; case FEMALE: System.out.println("male"); break; default: break; } } public enum Person{ MALE("M"), FEMALE("F"); private String value; Person(String value){ this.value = value; } public String getValue(){ return this.value; } }}
那它到底是怎么执行的呢?还是使用javap -c Main
看一下,如下:
从上我们发现,具体在底层实现的时候还是使用int
进行判断,只不过Enum
类型使用ordinal()
函数进行的转换。
2.3 隐式方法values()
通过使用values()
方法遍历其中的枚举常量,如下:
public static Person getPerson(String value){ return Arrays.asList(Person.values()).stream() .filter(person -> value.equalsIgnoreCase(person.getValue())) .findAny().get();}
2.4 EnumSet
&& EnumMap
伴随着Enum的出现也相应的出现了两个集合类EnumSet
、EnumMap
,由于这两个类从没使用过,所以就不展开说了,可以看如下的相关文章。
相关文章:
- Java 语言中 Enum 类型的使用介绍
- 关于Java 中Enum 的全方位剖析
- 关于Java中枚举Enum的深入剖析
- 关于Java中枚举Enum的深入剖析
- 关于Java中枚举Enum的深入剖析
- 关于Java中枚举Enum的深入剖析
- 关于java中枚举Enum的深入剖析
- java枚举enum剖析
- java中关于枚举enum类型的用法
- 关于java的枚举enum
- Java中enum的使用
- java中enum的使用
- Java中Enum的使用
- Java 中Enum 的扩展
- java 中enum的用法
- java中enum的用法
- Java中enum的本质
- Java中Enum的用法
- JAVA中【enum】的使用
- QUTOJ 1359: 小菜的难题 最小值最大化问题 二分
- setdest和cbrgen的使用
- YY LIVE年度盛典:孕育六载能否成就行业标杆?!
- $.fn. 给jQuery扩展插件
- 有关线程
- 关于Java 中Enum 的全方位剖析
- 深入理解Java:注解(Annotation)--注解处理器
- error link1158 无法运行rc.exe
- msyql centos服务器搭建
- 高通 msm平台GPIO相关的device tree设置
- 每天一指令
- base64 模块
- Android JNI学习笔记(四)-数据类型映射以及native调用java
- php运行环境安装与配置nginx