概述

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

    最终效果图: html文件: <!-- * @Qusetion: * @Author: 一届书生 * @Date: 2020-04-07 08:17:36 * @LastEditTime: 20 ...

  2. css3新单位vw、vh、vmin、vmax的使用详解

    1,vw.vh.vmin.vmax 的含义 (1) vw. vh. vmin. vmax 是一种视窗单位,也是相对单位.它相对的不是父节点或者页面的根节点.而是由视窗( Viewport)大小来决定的 ...

  3. vue2.0中watch用法

    watch:观测Vue实例上的数据变动,对应一个对象,键:就是需要监测的那个东西,值:1.可以是当键变化时执行的函数,有两个参数,第一个是变化前的值,第二个是变化后的值.2.可以是函数名,得用单引号包 ...

  4. Django框架——ajax补充、多对多三种创建、序列化组件、批量操作数据、分页器

    ajax补充说明 主要是针对回调函数args接收到的响应数据 1.后端request.is_ajax() 用于判断当前请求是否由ajax发出 2.后端返回的三板斧都会被args接收不再影响整个浏览器页 ...

  5. node统计指定文件夹内代码行数

    1. 来源 想对于自己接触前端日常学习与思考的代码行数进行一个统计,看自己大约敲了多少代码 2.代码 const fs = require('fs') const path = require('pa ...

  6. MySQL—一条查询SQL语句的完整执行流程

    MySQL-一条查询SQL语句的完整执行流程 表结构和数据如下: 我们分析的sql语句如下: select tb_id,tb_name,tb_address from tb_user where tb ...

  7. 力扣191(java)-位1的个数(简单)

    题目: 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为汉明重量). 提示: 请注意,在某些语言(如 Java)中,没有无符号整数类型. ...

  8. 一套 SQL 搞定数据仓库?Flink有了新尝试

    数据仓库是公司数据发展到一定规模后必然需要提供的一种基础服务,也是"数据智能"建设的基础环节.迅速获取数据反馈不仅有利于改善产品及用户体验,更有利于公司的科学决策,因此获取数据的实 ...

  9. Apache ShenYu 网关正式支持 Dubbo3 服务代理

    简介: 本文介绍了如何通过 Apache ShenYu 网关访问 Dubbo 服务,主要内容包括从简单示例到核心调用流程分析,并对设计原理进行了总结. 作者:刘良 Apache Dubbo 在去年发布 ...

  10. Gartner APM 魔力象限技术解读——全量存储? No! 按需存储?YES!

    简介: 在云原生时代,充分利用边缘节点的计算和存储能力,结合冷热数据分离实现高性价比的数据价值探索已经逐渐成为 APM 领域的主流. 作者:夏明(涯海) 调用链记录了完整的请求状态及流转信息,是一座巨 ...