原创文章,转载请标注出处:https://www.cnblogs.com/V1haoge/p/10755129.html

一、概述

枚举就是一个语法糖效果。

定义一个枚举,其实就是定义一个继承抽象类Enum的类。

了解了Enum,就能了解枚举。

二、Enum解析

2.1 接口

public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {}

枚举类实现了Comparable和Serializable接口,那么也就意味着,每个枚举类都拥有比较(有序)和序列化功能。

2.2 属性

public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
private final String name;
private final int ordinal;
public final String name() {
return name;
}
public final int ordinal() {
return ordinal;
}
}

这两个属性是枚举的内置属性,name表示的是枚举值的名称,ordinal表示的是枚举值的序号。

其作用后面再说

2.3 构造器

public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
}

Enum中只有这一个构造器,其申明为protected就是为了继承它的子类(我们定义的各种枚举)来调用的。

2.4 equals方法

public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
public final boolean equals(Object other) {
return this==other;
}
}

默认的equals方法底层就是使用实现的,所以在枚举的比较使用equals和都是可以的。前提是没有在枚举类中重写equals方法。

我们可以在自定义的枚举类中重写该方法,来实现我们自己的比较方式。

2.5 禁用的功能

public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
protected final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
protected final void finalize() { }
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
throw new InvalidObjectException("can't deserialize enum");
}
private void readObjectNoData() throws ObjectStreamException {
throw new InvalidObjectException("can't deserialize enum");
}
}

这四个方法均是被禁用的方法:

  • 克隆:目的为了保证单例唯一
  • finalize:禁用终引用
  • 序列化中禁用readObject和readObjectNoData方法:目的为了保证单例唯一

2.6 compareTo方法

public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
public final int compareTo(E o) {
Enum<?> other = (Enum<?>)o;
Enum<E> self = this;
if (self.getClass() != other.getClass() && // optimization
self.getDeclaringClass() != other.getDeclaringClass())
throw new ClassCastException();
return self.ordinal - other.ordinal;
}
}

这是实现了接口Comparable中的方法。用于定义比较的方式,可以看出这里是使用枚举值的序号作为比较条件的。

2.7 方法

public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
public static <T extends Enum<T>> T valueOf(Class<T> enumType,
String name) {
T result = enumType.enumConstantDirectory().get(name);
if (result != null)
return result;
if (name == null)
throw new NullPointerException("Name is null");
throw new IllegalArgumentException(
"No enum constant " + enumType.getCanonicalName() + "." + name);
}
}

该方法的作用是获取到指定枚举类型中指定枚举名称的枚举值。

三、枚举的实现

枚举是一种编译器语法糖。

我们使用enum关键字定义一个枚举,编译之后,编译器会对其进行加工,具体如下:

  1. 编译成为class类型,并继承自Enum
  2. 添加静态的values方法,用于获取所有枚举值的数组
  3. 添加valueOf方法,实现Enum中的valueOf方法,可以根据具体的枚举值名称字符串获取对应的枚举值
  4. 添加私有构造器,其中调用Enum中定义的唯一的构造器
  5. 定义静态常量枚举值
  6. 添加静态块为这些静态枚举常量赋值

通过上面一些列加工之后,枚举类被解析为一个普通的类,类名不变。

Java基础系列-Enum深入解析的更多相关文章

  1. 夯实Java基础系列3:一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!

    目录 目录 string基础 Java String 类 创建字符串 StringDemo.java 文件代码: String基本用法 创建String对象的常用方法 String中常用的方法,用法如 ...

  2. 夯实Java基础系列15:Java注解简介和最佳实践

    Java注解简介 注解如同标签 Java 注解概述 什么是注解? 注解的用处 注解的原理 元注解 JDK里的注解 注解处理器实战 不同类型的注解 类注解 方法注解 参数注解 变量注解 Java注解相关 ...

  3. Java基础系列-ArrayList

    原创文章,转载请标注出处:<Java基础系列-ArrayList> 一.概述 ArrayList底层使用的是数组.是List的可变数组实现,这里的可变是针对List而言,而不是底层数组. ...

  4. Java基础系列-二进制操作

    原创文章,转载请标注出处:<Java基础系列-二进制操作> 概述 Java源码中涉及到大量的二进制操作,非常的复杂,但非常的快速. Java二进制表示法 首先了解下二进制,二进制是相对十进 ...

  5. Java基础系列-Comparable和Comparator

    原创文章,转载请标注出处:<Java基础系列-Comparable和Comparator> 一.概述         Java中的排序是由Comparable和Comparator这两个接 ...

  6. Java基础系列--HashMap(JDK1.8)

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10022092.html Java基础系列-HashMap 1.8 概述 HashMap是 ...

  7. 夯实Java基础系列14:深入理解Java枚举类

    目录 初探枚举类 枚举类-语法 枚举类的具体使用 使用枚举类的注意事项 枚举类的实现原理 枚举类实战 实战一无参 实战二有一参 实战三有两参 枚举类总结 枚举 API 总结 参考文章 微信公众号 Ja ...

  8. Java基础系列2:深入理解String类

    Java基础系列2:深入理解String类 String是Java中最为常用的数据类型之一,也是面试中比较常被问到的基础知识点,本篇就聊聊Java中的String.主要包括如下的五个内容: Strin ...

  9. 2015年12月28日 Java基础系列(六)流

    2015年12月28日 Java基础系列(六)流2015年12月28日 Java基础系列(六)流2015年12月28日 Java基础系列(六)流

随机推荐

  1. laravel 中路由的快速设置(只需一个控制器名就ok) 不用具体到方法

    routes/web.php 设置路由 Route::group(['middleware' => ['\iqiyi\Http\Middleware\VerifyCsrfToken::class ...

  2. Hadoop2.41的HA的配置与启动

    我配置HA机制创建了7台虚拟机 1.修改Linux主机名2.修改IP3.修改主机名和IP的映射关系 ######注意######如果你们公司是租用的服务器或是使用的云主机(如华为云主机.阿里云主机等) ...

  3. js操作中要去注意的一些问题

    1.js中注意问题 font-size 改成fontSize padding-top 改成paddingTop js中不认识-,所以要以小驼峰方式操作属性或者以[" "]方式,例[ ...

  4. 基于docker 如何部署surging分布式微服务引擎

    1.前言 转眼间surging 开源已经有1年了,经过1年的打磨,surging已从最初在window 部署的分布式微服务框架,到现在的可以在docker部署利用rancher 进行服务编排的分布式微 ...

  5. TensorFlow之DNN(三):神经网络的正则化方法(Dropout、L2正则化、早停和数据增强)

    这一篇博客整理用TensorFlow实现神经网络正则化的内容. 深层神经网络往往具有数十万乃至数百万的参数,可以进行非常复杂的特征变换,具有强大的学习能力,因此容易在训练集上过拟合.缓解神经网络的过拟 ...

  6. 聚焦“云开发圆桌论坛”,大前端Serverless大佬们释放了这些讯号!

    4月14日,由云加社区举办的TVP&腾讯云技术交流日云开发专场,暨"腾讯云-云开发圆桌论坛"在北京.深圳两地同步举行. 当天下午,一场主题为"基于大前端和node ...

  7. MySQL 数据库字符集 utf8 和 utf8mb4 的区别

    参考于今日头条上Java芋道源码的-----记住:永远不要在 MySQL 中使用 UTF-8 字符集选择 MySQL 的 utf8 实际上不是真正的 UTF-8.utf8 只支持每个字符最多三个字节, ...

  8. SpringBoot之旅第一篇-初探

    一.SpringBoot是什么? 微服务,应该是近年来最火的概念,越来越多的公司开始使用微服务架构,面试中被问到的微服务的概率很高,不管对技术的追求,还是为了进更好的公司,微服务都是我们开发人员的必须 ...

  9. .net之设计模式

    在上一篇文章里我通过具体场景总结了“.net面向对象的设计原则”,其中也多次提到一些设计模式方面的技术,可想而知,设计模式在我们的开发过程中也是必不可少的.今天我们就来简单交流下设计模式.对于设计模式 ...

  10. sqlserver的over开窗函数(与排名函数或聚合函数一起使用)

    首先初始化表和数据 create table t_student(   Id INT,   Name varchar(),   Score int,   ClassId INT ); insert i ...