概述

在此之前由于个人在学习和开发中对枚举类的应用较少,所以对枚举类的知识点并没进行深入的了解,但最近写代码中突然想到了枚举类,抱着完善自身的知识的目的,就较为深入的了解了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. Qt 排序 QSort

    一.对整形排序 // qSort 对整形排序 QList<int> list; list << 1 << 3 << 19 << 0 < ...

  2. Cert Manager 申请SSL证书流程及相关概念-二

    中英文对照表 英文 英文 - K8S CRD 中文 备注 certificates Certificate 证书 certificates.cert-manager.io/v1 certificate ...

  3. HarmonyOS实现静态与动态数据可视化图表

    一. 样例介绍 本篇Codelab基于switch组件和chart组件,实现线形图.占比图.柱状图,并通过switch切换chart组件数据的动静态显示.要求实现以下功能: 1.  实现静态数据可视化 ...

  4. 应用可靠性与性能不给力?HarmonyOS HiViewDFX了解一下

    原文链接:https://mp.weixin.qq.com/s/Y44jUEB3ttlijbMDPrBcNg,点击链接查看更多技术内容:   作为基础软件服务子系统的HarmonyOS HiViewD ...

  5. Spring6

    0x00 环境配置 环境: IDEA >= 2022.1.4 JDK 17 Maven 3.8.6 Spring 6.0.0 JUnit 4.13.2 Log4j2 新建模块 spring001 ...

  6. centos8 \CentOS 9 Stream rpm 安装mysql8.0.28

    centos8 rpm 安装mysql8.0.28 检查 检测系统是否自带安装 MySQL 命令如下: rpm -qa | grep mysql 如果如下存在已安装的包,就需要卸载 mysql80-c ...

  7. CentOS8 / CentOS7 yum源最新修改搭建 2022.3.1

    Part I CentOS 8 源更新 ========================================== 2022年过完后,发现公司里面的所有服务器yum都不能用了,一直报错 按照 ...

  8. CentOS 6.5快速部署HTTP WEB服务器和FTP服务器

    CentOS 6.5快速部署HTTP WEB服务器和FTP服务器 时间:2014-03-29    来源:服务器之家    投稿:root    点击:210次 [题记]本文使用CentOS 6.5m ...

  9. redis 简单整理——慢查询[八]

    前言 简单整理一下redis的慢查询. 正文 什么是慢查询呢? 一般存储系统就是系统在命令执行前后计算每条命令的执行时间,当超出预设阀值,就将这条命令的相关信息记录下来. 但是有人可能没有看到慢查询日 ...

  10. 力扣1083(MySQL)-销售分析Ⅱ(简单)

    题目: 编写一个 SQL 查询,查询购买了 S8 手机却没有购买 iPhone 的买家.注意这里 S8 和 iPhone 是 Product 表中的产品. 查询结果格式如下图表示: Product t ...