一文快速掌握 java 枚举的用法

独钓渔 2020-11-11 23:26:07
java 设计模式 jdk


一、枚举

在数学和计算机科学理论中,一个数据集的枚举 是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。枚举,就是一个可列举的有限对象的集合。

JDK1.5之前,需要自定义枚举类;

JDK1.5之后,可以使用 enum 关键字定义枚举类,写法超级简单;

JDK1.6之后,switch 语句支持枚举,使代码更简洁更健壮;

若枚举类只有一个成员,则可以作为一种单例模式的实现方式,也就是说,单例模式可以看做枚举的一个特例;

1. 应用场景

可以应用到所有可以定义出有限个值的场景,常常用于设定为常量,比如:

  1. 一年有四季,定义四季的名称;
  2. 一年有12个月,定义月份的名称;
  3. 所有颜色都是有3个原色组成的,可以定义3个原色;

2. 典型应用

线程的状态是使用枚举类实现的,java.lang.Thread.State,可以看到其定义了线程的各个状态。

@Test
public void testTheadState(){
//获取枚举对象,并循环输出
Thread.State[] states = Thread.State.values();
for(Thread.State s : states){
System.out.println(s);
}
}

运行结果:

 NEW
RUNNABLE
BLOCKED
WAITING
TIMED_WAITING
TERMINATED

二、代码实现

1. 自定义枚举类

/**
* 自定义实现的枚举类——季节
* 枚举是可列举的有限个对象的集合,一年只有四季,都可以列举出来,故适合采用枚举形式
* 自定义枚举类的写法和单例模式类似,或者可以说,单例模式就是枚举类只有一个对象的特例。
*
* 自定义枚举类有以下关键点:
* 1. 枚举类的构造方法必须私有化,不允许外部调用,防止通过外部改变枚举对象;
* 2. 枚举类的属性必须定义为private final,避免外部修改;
* 3. 枚举类需要自己创建枚举对象,枚举对象必须定义为public static final,提供外部访问方式。
*
* @author hello
* @date 2020/11/06
*/
public class CustomSeasonEnum {
/**
* 属性定义为private final,避免被外部修改
*/
private final String seasonName;
private final String seasonDesc;
/**
* 构造方法私有化,可指定构造方法的参数,方便实例化时赋值
*/
private CustomSeasonEnum(String seasonName, String seasonDesc){
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
/**
* 定义枚举对象,最关键的地方
*/
public static final CustomSeasonEnum SPRING =
new CustomSeasonEnum("Spring","春风拂面");
public static final CustomSeasonEnum SUMMER =
new CustomSeasonEnum("Summer","生如夏花");
public static final CustomSeasonEnum AUTUMN =
new CustomSeasonEnum("Autumn","秋风瑟瑟");
public static final CustomSeasonEnum WINTER =
new CustomSeasonEnum("Winter","冬日暖阳");
}

编写测试用例如下:

public class CustomSeasonEnumTest {
@Test
public void testCustomEnum(){
CustomSeasonEnum season = CustomSeasonEnum.SPRING;
System.out.println(season.getSeasonName() + " : " + season.getSeasonDesc());
}
}

运行结果:可以看到,调用正确

 Spring : 春风拂面

2. 使用enum关键字定义枚举类

2.1 使用enum定义的枚举类

使用enum定义的枚举类,只是一种简化了形式的自定义枚举类,其也可以包含自定义属性、方法、构造方法等,相比自定义枚举类,简化了枚举对象的声明,省略了public static final及new 对象等语句,枚举对象的定义是线程安全的,故也可以使用枚举方式定义单例模式。

与自定义枚举类相比,使用enum枚举类有以下特点:

  1. 枚举对象必须放到最前面,也就是必须在其他自定义属性或方法的签名;
  2. 忽略了public static final 及 new 对象等语句;
/**
* 使用enum关键字定义的枚举值
*/
public enum SeasonEnum {
/**
* 一年四季,依次为:春天、夏天、秋天、冬天
* 相比自定义枚举方式:
* 1. 必须放到最前面,也就是必须在其他自定义属性或方法的签名;
* 2. 忽略了public static final 及 new 对象等语句;
*/
SPRING("Spring","春风拂面"),
SUMMER("Summer","生如夏花"),
AUTUMN("Autumn","秋高气爽"),
WINTER("Winter","冬日暖阳");
/**
* 枚举类的属性
*/
private final String seasonName;
private final String seasonDesc;
/**
* 构造方法私有化
*/
private SeasonEnum(String seasonName, String seasonDesc){
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
/**
* 获取属性的公共方法
*/
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
}

2.2 最简单的枚举类示例

最简单的枚举形式是只有枚举对象,没有任何属性,也不声明构造方法,也没有定义方法。

//最简单的枚举示例
public enum ColorEnum {
RED,GREEN,BLUE;
}
//测试用例
@Test
public void testColorEnum(){
//获取红色
ColorEnum red = ColorEnum.RED;
System.out.println(red);
System.out.println("------");
//获取所有对象
ColorEnum[] colors = ColorEnum.values();
for (ColorEnum colorEnum : colors){
System.out.println(colorEnum);
}
}

运行结果:

 RED
------
RED
GREEN
BLUE

2.3 常用方法

2.3.1 values()

 

方法作用:获取所有的枚举对象数组,可以依次遍历,并做相应判断;

方法示例:

@Test
public void testValues(){
ColorEnum[] colorEnums = ColorEnum.values();
for(ColorEnum colorEnum : colorEnums){
System.out.println(colorEnum);
}
}
//运行结果:
RED
GREEN
BLUE

2.3.2 valueOf(String name)

方法作用:根据字符串获取相同名称的枚举对象;

注意事项:

  1. 要求传入的字符串名称必须是枚举对象的名称,不能随意输入;
  2. 若字符串输入错误,并不是返回null,而是程序报错;

方法示例:

(1)正确示例:获取对应名称的枚举对象

 @Test
public void testValueOf(){
String colorName = "RED";
ColorEnum colorEnum = ColorEnum.valueOf(colorName);
System.out.println(colorEnum);
}
//运行结果:
RED

(2)错误示例:抛出异常IllegalArgumentException

@Test
public void testValueOfError(){
String colorName = "REEEEED";
ColorEnum colorEnum = ColorEnum.valueOf(colorName);
System.out.println(colorEnum);
}
//运行结果:抛出异常IllegalArgumentException
java.lang.IllegalArgumentException: No enum constant com.tengol.demo.javase.basic.enums.ColorEnum.REEEEED
at java.lang.Enum.valueOf(Enum.java:238)
at com.tengol.demo.javase.basic.enums.ColorEnum.valueOf(ColorEnum.java:3)

2.4 枚举类实现接口

使用enum关键字定义的枚举类都继承自抽象类java.lang.Enum,因为Java不支持多继承,所以枚举类无法再继承其它类,但可以实现一个或者多个接口。

枚举类可以实现接口,同时枚举对象也可以重写所实现接口的抽象方法,通过反编译方式可以看到,枚举对象重写接口方法时通过匿名内部类方式实现。

第一步:定义接口

/**
* 接口:打印信息
*/
public interface Info {
public void print();
}

第二步:枚举类实现接口方法,枚举对象可以重写方法

public enum WeekEnum implements Info {
/**
* 一周七天
*/
MONDAY{
@Override
public void print() {
super.print();
}
},
TUESDAY{
@Override
public void print() {
System.out.println("Tuesday...");
}
},
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY;
public void print() {
System.out.println("WeekEnum...");
}
}

测试用例:

@Test
public void testImpl(){
//周二重写了print()方法,执行重写的方法
WeekEnum tue = WeekEnum.TUESDAY;
tue.print();
//周三未重写,执行WeekEnum的print()方法
WeekEnum wed = WeekEnum.WEDNESDAY;
wed.print();
}

运行结果:

Tuesday...
WeekEnum...

部分笔记内容来自尚硅谷的培训视频,如有兴趣,请关注。

版权声明
本文为[独钓渔]所创,转载请带上原文链接,感谢
https://my.oschina.net/lenglingx/blog/4713374

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云