概述

在此之前由于个人在学习和开发中对枚举类的应用较少,所以对枚举类的知识点并没进行深入的了解,但最近写代码中突然想到了枚举类,抱着完善自身的知识的目的,就较为深入的了解了Java中的枚举类。

我在学习任何东西之前都会大致弄清楚这个东西存在的目的是什么,这样才能更加深入的理解一些东西。同样的,在学习枚举类之前,我们也需要摸清楚Java5才出来的枚举类到底有什么作用。

为什么会出现枚举类

这里我们给出一种场景,给出一个Employee类,该类需要定义一个字段保存这个员工休息日(周一到周日的一天),那我们如何表示呢?


有人可能就说了直接定义成int型不就行了,1表示星期一.....。代码也就是这样的:

public class Employee {
private String name;
private int playday; public Employee(String name, int playday) {
super();
this.name = name;
this.playday = playday;
}
}

但是问题来了,使用这个类的用户怎么知道传进去的数字代表的是什么,更危险的是用户可以传入一个负数,这显然就不符合要求了。可能有些人就会说了,在方法上面写一个注释不就行了,但是这么做明显是把命运交给了别人,万一别人就是不按规定来呢?


我们来对程序做第一版改进:

public class Employee {
public static final int Mon=1;
public static final int Tues=2;
public static final int Wed=3;
public static final int Thur=4;
public static final int Fri=5;
public static final int Sat=6;
public static final int Sun=7; private String name;
private int playday; public Employee(String name, int playday) {
super();
this.name = name;
this.playday = playday;
}
}

这样我们每次在创建Employee对象过程中传入int类型值时就不需要手动指定一个常量值了,只需要使用Employee中定义的静态常量即可。就像这样:

Employee employee = new Employee("zhangsan", Employee.Fri);

但是这么做并没有完全解决上面所说的问题,用户还是可以手动指定指定一个整数类型的值。看来我们还需要对程序进行改进:


第二版改进:我们需要重新定义一个类来表示星期了!

public class WeekDay {
public static final WeekDay Mon=new WeekDay(1, "Mon");
public static final WeekDay Tues=new WeekDay(2, "Tues");
public static final WeekDay Wed=new WeekDay(3, "Wed");
public static final WeekDay Thur=new WeekDay(4, "Thur");
public static final WeekDay Fri=new WeekDay(5, "Fri");
public static final WeekDay Sat=new WeekDay(6, "Sat");
public static final WeekDay Sun=new WeekDay(7, "Sun"); private int day;
private String info; //构造器被私有化
private WeekDay(int day, String info) {
super();
this.day = day;
this.info = info;
}
}

此时Employee类需要进行相应的改进

public class Employee {
private String name;
private WeekDay playday; public Employee(String name, WeekDay playday) {
super();
this.name = name;
this.playday = playday;
}
}

经过两次改进程序得到了完善,由于WeekDay类的构造器被私有化(别和我杠可以通过反射等手段获得新的WeekDay对象),所以用户在创建Employee对象时只能使用WeekDay中的静态常量了,所以最初的那些问题也就解决了。

但是!!!!!!!!

你没觉得这么写太麻烦了吗?为了Employee类中的一个属性,需要重新建一个表示常量的类,并且代码还比较多,此时Java5出来的特性——枚举类就可以简单的解决这个问题了。

引入枚举类

Java 5新增了一个enum关键字(表面上看它与class interface地位相同),用于定义枚举类。

我们通过枚举类对第二次改版的代码进行改造:

定义枚举类:

public enum WeekDayEnum {
Mon,Tues,Wed,Thu,Fri,Sat,Sun;
}

改造Employee类:

public class Employee {
private String name;
private WeekDayEnum playday; public Employee(String name, WeekDayEnum playday) {
super();
this.name = name;
this.playday = playday;
}
}

创建Employee对象:

Employee lisi = new Employee("lisi", WeekDayEnum.Mon);

这么写代码是不是发现简单了很多,文化人要说“优雅”这个词,哈哈。

那我们就来说说Java中的枚举类的语法规则:

1. 枚举类的所有的常量(或者说是枚举类的实例)必须在第一行中列出来,常量与常量之间用逗号隔开,列出来的常量系统会自动加上 public static final修饰符,不需要程序员手动添加。

2. 枚举类可以实现一个或多个接口。

3. 枚举类的构造器只能用只能使用private修饰,不然会报错,如果省略修饰符那么系统会默认加上private。

4. 枚举类底层继承至Enum类,所以枚举类不可继承其它类

5. 枚举类底层由final修饰,所以它不可被其它类继承

6. 枚举类可以拥有静态和非静态方法。

你以为说完枚举类的语法,枚举类就学完了??

哪有这么简单。。。。

深入理解枚举类

我们将WeekDayEnum类通过XJad反编译工具进行反编译,反编译的结果如下:

public final class WeekDayEnum extends Enum
{ public static final WeekDayEnum Mon;
public static final WeekDayEnum Tues;
public static final WeekDayEnum Wed;
public static final WeekDayEnum Thu;
public static final WeekDayEnum Fri;
public static final WeekDayEnum Sat;
public static final WeekDayEnum Sun;
private static final WeekDayEnum ENUM$VALUES[]; private WeekDayEnum(String s, int i)
{
super(s, i);
} public static WeekDayEnum[] values()
{
WeekDayEnum aweekdayenum[];
int i;
WeekDayEnum aweekdayenum1[];
System.arraycopy(aweekdayenum = ENUM$VALUES, 0, aweekdayenum1 = new WeekDayEnum[i = aweekdayenum.length], 0, i);
return aweekdayenum1;
} public static WeekDayEnum valueOf(String s)
{
return (WeekDayEnum)Enum.valueOf(cn/tjd/enumtest/WeekDayEnum, s);
} static
{
Mon = new WeekDayEnum("Mon", 0);
Tues = new WeekDayEnum("Tues", 1);
Wed = new WeekDayEnum("Wed", 2);
Thu = new WeekDayEnum("Thu", 3);
Fri = new WeekDayEnum("Fri", 4);
Sat = new WeekDayEnum("Sat", 5);
Sun = new WeekDayEnum("Sun", 6);
ENUM$VALUES = (new WeekDayEnum[] {
Mon, Tues, Wed, Thu, Fri, Sat, Sun
});
}
}

哇,你会发现这个类和我们当初写的WeekDay类怎么很相似呢?

反编译后的关注点:

1. 枚举类默认继承java.lang.Enum类,而不是传统类的Object父类。

2. 类名用final修饰,也就是说枚举类不能有子类继承它。

3. 构造器是私有的。

细细体会反编译的源码。。。。。

枚举类的其他用法

这里我值提供一些思路:

1. 枚举类可以用于做常量,也就是我们上面所描述的。

2. 枚举类可以写单例模式,并且可以防止通过反射或序列化进行单例攻击。

参考这篇文章:https://www.cnblogs.com/chiclee/p/9097772.html

3. 可以用在switch语句中做分支判断。。

等.....

原创不易啊!!走过路过不要错过,帮博主点个赞吧,嘻嘻!!

Java中枚举类的深入理解的更多相关文章

  1. java中枚举类的实际应用

    知识点:在Java中,使用枚举类,当遇到实例类型有限的类时,并且数据库中用状态码代表一种含义时,如星期,性别,员工登陆某系统的状态等等, 可以考虑使用枚举类 本例子可以仿照,也可以使用自定义的类型处理 ...

  2. java中枚举类的使用详解

    /* * 通过JDK5提供的枚举来做枚举类 */ public enum Direction2 { FRONT("前"), BEHIND("后"), LEFT( ...

  3. java中枚举类到高级使用

    参考博文: http://blog.csdn.net/qq_31655965/article/details/55049192 http://www.cnblogs.com/zhaoyanjun/p/ ...

  4. 基础知识(05) -- Java中的类

    Java中的类 1.类的概念 2.类中的封装 3.对象的三大特征 4.对象状态 5.类与类之间的关系 ------------------------------------------------- ...

  5. 第四节:详细讲解Java中的类和面向对象思想

    前言 大家好,给大家带来详细讲解Java中的类和面向对象思想的概述,希望你们喜欢 类和面向对象 在Java中怎样理解对象,创建对象和引用:什么是引用,对于基础学习的同学,要深入了解引用.示例:Stri ...

  6. Java中枚举的使用

    Java中枚举其实就是静态常量,今天发现枚举里面其实还能加方法,学习了下, 代码如下: package org.pine.test; import java.util.HashMap; import ...

  7. Java中Optional类的使用

    从 Java 8 引入的一个很有趣的特性是 Optional  类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都 ...

  8. 细说java中的类

    前言 最近在学习<java编程思想> 学到了内部类 类不就是class吗 天天用 还能讲出花来了不成... 其实不然,在java中,类的种类和使用方式多种多样,花样繁多.其中主要有 普通类 ...

  9. Java中枚举的写法和用法

            在公司代码中,用了一大堆的枚举,看得我好懵逼.下面开始看看枚举怎么写和怎么用. 一.枚举的写法         关于枚举的写法,网上好多这方面的知识.这里直接贴一个我自己写的枚举类的代 ...

  10. java基础---->Java中枚举的使用(一)

    这里介绍一下java中关于枚举的使用. java中枚举的使用 一.枚举中可以定义方法 参照于TimeUnit的使用,TimeUnit.MILLISECONDS.sleep(1000); LoveUti ...

随机推荐

  1. Python读写json文件--json

    import json # 将数据写入json文件 def json_write_file(): data={'name':'张三','age':12} with open('json.json',' ...

  2. Python删除文件、文件夹----os

    使用 os  删除文件 import os '''删除文件 语法: os.unlink(path) 示例: 删除 b 文件夹中的 12.txt ''' os.unlink('b/12.txt')   ...

  3. Centos8防火墙配置、端口、进程管理

    Centos8停用.启用.查看当前启用的端口 firewall-cmd --zone=public --add-port=5672/tcp --permanent # 开放5672端口 firewal ...

  4. mac笔记本esc按键失灵(系统13ventura13.3.1 2019款i7)

    1.原因 mac系统存在bug,有几率碰到,此时siri卡死无法唤出,笔记本使用了一年多接近两年,第一碰到 2.解决方案 重启 任务管理器杀掉siri

  5. 力扣613(MySQL)-直线上的最近距离(简单)

    题目: 表 point 保存了一些点在 x 轴上的坐标,这些坐标都是整数. 写一个查询语句,找到这些点中最近两个点之间的距离. 最近距离显然是 '1' ,是点 '-1' 和 '0' 之间的距离.所以输 ...

  6. 力扣172(java)-阶乘后的零(中等)

    题目: 给定一个整数 n ,返回 n! 结果中尾随零的数量. 提示 n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1 示例 1: 输入:n = 3输出:0解释: ...

  7. 注册配置、微服务治理、云原生网关三箭齐发,阿里云 MSE 持续升级

    简介: MSE 云原生网关作为托管型的独享实例,与部署业务应用的资源解耦,并支持过载保护.故障自愈.限流降级等功能,确保流量高峰时的稳定性.其优异的性能表现使费芮不需要高规格的资源配置即可支撑大规模的 ...

  8. 这是阿里技术专家对 SRE 和稳定性保障的理解

    简介: 在技术工作中,对于产品/基础技术研发和 SRE 两种角色,通常会有基于「是否侧重编码」的理解.对于产品研发转做 SRE ,经常会产生是否要「脱离编码工作」的看法,或者认为是否要「偏离对产品/基 ...

  9. 实时计算 Flink 版总体介绍

    简介: 实时计算 Flink 版(Alibaba Cloud Realtime Compute for Apache Flink,Powered by Ververica)是阿里云基于 Apache ...

  10. 基于英特尔® 优化分析包(OAP)的 Spark 性能优化方案

    ​简介: Spark SQL 作为 Spark 用来处理结构化数据的一个基本模块,已经成为多数企业构建大数据应用的重要选择.但是,在大规模连接(Join).聚合(Aggregate)等工作负载下,Sp ...