概述

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

    本示例,为纯Qt调用摄像头,功能会比版本一要多一点:打开摄像头,设置参数,完整拍照,框选拍照,切换分辨率,旋转,水平镜像,垂直镜像,放大,缩小 上一个版本,使用的显示窗口直接显示出摄像头画面,所以可操 ...

  2. keycloak~RequiredActionProvider的使用

    使用场景 RequiredActionProvider,它是在认证过程中,需要当前登录的用户执行个性化的动作:当用户符合条件,就被执行RequiredActionProvider对作,当Require ...

  3. 优先队列的基本实现【数据结构与算法—TypeScript 实现】

    笔记整理自 coderwhy 『TypeScript 高阶数据结构与算法』课程 特性 效率比普通队列高 每个出队元素拥有最高优先级 可以用 数组.链表 等数据结构实现,但是 堆结构 是最常用的实现方式 ...

  4. nginx重新整理——————http请求的11个阶段中的access阶段[十五]

    前言 简单介绍一下access 阶段. 正文 限制某些ip地址的访问权限: syntax: allow address| CIDR|unix:|all; defuat: - context: http ...

  5. js 如何实现管道或者说组合

    前言 概念:管道是从左往右函数执行,组合是从右往左执行. 实现 原理与作用后续补齐. function compose(...funcs) { return function(x) { funcs.r ...

  6. 升级gradle:Could not find method jackOptions() for arguments

    前言 这是我在升级gradle发生的错误. 解决 原因是被废弃了: 删除: jackOptions { enabled true } 解释一下什么是jack: Jack 是 Java Android ...

  7. LeetCode - 最接近的三数之和

    最接近的三数之和 你一个长度为 n 的整数数组 nums 和 一个目标值 target.请你从 nums 中选出三个整数,使它们的和与 target 最接近. 返回这三个数的和. 假定每组输入只存在恰 ...

  8. 顺通ERP:精细敏捷的设计理念,得到了消费者的喜爱

    顺通ERP是近年来备受关注的一款ERP品牌,其设计精细,操作便捷,备受消费者喜爱.那么,顺通ERP到底怎么样呢?属于什么档次呢? 首先,从品质上来看,顺通ERP具备高度的稳定性,能够确保企业的日常运营 ...

  9. 对于小程序canvas在某些情况下touchmove 不能触发导致的签名不连续替代方案(企微)

    1.问题 微信开放社区链接 尝试过新版canvas,在企业微信中签名依然是依然断触,有问题的手机是iphoe15,系统版本以及企微版本微信版本均与签名正常的手机一致,但是那个手机就是无法正常签字,在微 ...

  10. 【Oracle】Oracle常用分析函数(排名)

    Oracle常用分析函数(排名) 一般来说,遇到需要对数据进行排序的时候,可以使用分析函数,一般常用的有三个,rank,dense_rank,row_number --Oracle常用分析函数(排名) ...