1、引言

枚举类型是 JDK 5 之后引进的一种非常重要的引用类型,可以用来定义一系列枚举常量。相比与常量(public static final定义),在安全性、指意性、可读性方面更胜一筹。另外它可以和switch case搭配使用。

2、类定义

实际上在使用关键字enum创建枚举类型并编译后,编译器会为我们生成一个相关的类,这个类继承了Java API中的java.lang.Enum类,也就是说通过关键字enum创建枚举类型在编译后事实上也是一个类类型而且该类继承自java.lang.Enum类,并且该类类型是final修饰的,无法被继承。

public abstract class Enum>implements Comparable, Serializable {}

3、成员属性

// 枚举常量的名称

private final String name;

// 它和不重写的toString()方法返回的是一样的,只不过toString()方法可以进行重写定制。

public final String name() {

return name;

}

/**

* 枚举常量的序号(它在枚举声明中的位置,其中初始常量的序号为零)。

* 代码中尽量避免使用该值,因为我们有时候添加新枚举时,总是“按组”放在一起,不会放到最后,除非强制要求。

* 比如接口响应码的枚举,我们通常会把参数异常的放一组,内部异常的放一组等。如果参数异常新添加一个枚举“xx不存在”,如果这个枚举没有放在整个接口响应码枚举的末尾,而是放到了某一组的末尾,那么部分枚举常量的ordinal值就发生了变化。这将是灾难性的,所以要么代码规范添加新枚举只能添加到末尾;要么不使用该值。

*/

private final int ordinal;

public final int ordinal() {

return ordinal;

}

4、构造方法

// 唯一的构造方法,程序员调用不到,它由编译器发出的代码用于响应枚举类型声明。

protected Enum(String name, int ordinal) {

this.name = name;

this.ordinal = ordinal;

}

5、其他方法

// 返回声明中包含的此枚举常量的名称。 可以覆盖该方法,但通常不需要或不需要。

public String toString() {

return name;

}

public final boolean equals(Object other) {

return this==other;

}

// 这里调用的是Object的hashCode方法

public final int hashCode() {

return super.hashCode();

}

// 不能克隆,保证了枚举永远是单例的,所以枚举是单例模式的典型代表

protected final Object clone() throws CloneNotSupportedException {

throw new CloneNotSupportedException();

}

// 这里需要注意,底层的实现用的是ordinal实现的,即比较的是枚举常量的序号。

public final int compareTo(E o) {

Enum> other = (Enum>)o;

Enum self = this;

if (self.getClass() != other.getClass() &&

self.getDeclaringClass() != other.getDeclaringClass())

throw new ClassCastException();

return self.ordinal - other.ordinal;

}

// 返回与此枚举常量的枚举类型相对应的 Class 对象。

public final Class getDeclaringClass() {

Class> clazz = getClass();

Class> zuper = clazz.getSuperclass();

return (zuper == Enum.class) ? (Class)clazz : (Class)zuper;

}

// 枚举不能有finalize方法

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");

}

/**

* 返回简单名称到枚举常量的映射。

* name的值必须与用于声明此类型的枚举常量的标识符完全一致。

*

* 对于特定的枚举类型T,有两个隐式声明的方法可以直接使用:

* 1) public static T valueOf(String) 根据名称获取单个枚举类型;这个我深有体会,因为之前是不知道有这个方法,通常是用values()获取枚举集合map,然后遍历

* 2) public static T[] values() 获取所有枚举类型数组;

*/

public static > T valueOf(Class 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);

}

/**

* 1)该方法是属于java.lang.Class,不是java.lang.Enum的方法;

* 2)enumConstantDirectory 是一个map,定义如下:private volatile transient Map enumConstantDirectory = null;其中key为枚举的name,value为枚举。

* 3)enumConstantDirectory()方法获取枚举常量目录,没有就继续调用getEnumConstantsShared();如果有返回值,就遍历put进enumConstantDirectory。

*/

Map enumConstantDirectory() {

if (enumConstantDirectory == null) {

T[] universe = getEnumConstantsShared();

if (universe == null)

throw new IllegalArgumentException(

getName() + " is not an enum type");

Map m = new HashMap<>(2 * universe.length);

for (T constant : universe)

m.put(((Enum>)constant).name(), constant);

enumConstantDirectory = m;

}

return enumConstantDirectory;

}

7、枚举隐式实现的方法

如上所说,枚举自动继承这两个隐式方法。这两个方法很重要,所以我在这里单拎出来了。

// 根据名称获取单个枚举类型

public static T valueOf(String){}

// 获取所有枚举类型数组

public static T[] values(){}

8、枚举集合

这两个是枚举优化过后的集合,比HashSet,HashMap的性能更高。

8.1、EnumSet

8.2、EnumMap

java java.lang.enum_源码阅读-java基础-java.lang.Enum相关推荐

  1. 源码阅读(34):Java中线程安全的Queue、Deque结构——ArrayBlockingQueue(4)

    (接上文<源码阅读(33):Java中线程安全的Queue.Deque结构--ArrayBlockingQueue(3)>) 2.3.3.3.forEachRemaining() 方法 f ...

  2. 源码阅读(32):Java中线程安全的Queue、Deque结构——ArrayBlockingQueue(2)

    (接上文<源码阅读(31):Java中线程安全的Queue.Deque结构--ArrayBlockingQueue(1)>) 本篇内容我们专门分析ArrayBlockingQueue中迭代 ...

  3. java io中断_JDK源码阅读:InterruptibleChannel 与可中断 IO

    来源:木杉的博客 , imushan.com/2018/08/01/java/language/JDK源码阅读-InterruptibleChannel与可中断IO/ Java传统IO是不支持中断的, ...

  4. Binder源码阅读指南之java层,作为Android开发程序员

    // Find the service manager sServiceManager = ServiceManagerNative.asInterface(Binder.allowBlocking( ...

  5. Java多线程类FutureTask源码阅读以及浅析

    FutureTask是一个具体的实现类,实现了RunnableFuture接口,RunnableFuture分别继承了Runnable和Future接口,因此FutureTask类既可以被线程执行,又 ...

  6. java cloneable 接口_JDK源码阅读笔记-Cloneable接口

    JDK 版本:1.8 代码地址 1.前言 clone方法能方便的获得一个对象的拷贝,但其中也有些细节需要注意. 2.实现注意事项 2.1 要调用 clone 方法必须实现 Cloneable 接口 如 ...

  7. java 挂机锁屏 源码_挂机界面 - java代码库 - 云代码

    [java]代码库//挂机 package com.view; import java.awt.Color; /** * 挂机界面 * @author Administrator * */ publi ...

  8. Java功能模块代码源码_Windows计算机功能Java源码

    代码如下 import java.awt.Color; import java.awt.Container; import java.awt.GridLayout; import java.awt.e ...

  9. java电商项目源码_电子商务系统+java+web+完整项目+包含源码和数据库Java实用源码...

    本篇我们根据架构图进行代码的构建.根据微服务化设计思想,结合spring cloud一些优秀的项目,如服务发现.治理.配置化管理.路由负载.安全控制等优秀解决方案,使用Maven技术将框架进行模块化. ...

最新文章

  1. 迁移学习与图神经网络“合力”模型:用DoT-GNN克服组重识别难题
  2. 杭州码农哀叹:新买的房子装修到一半没钱了,靠着贷款平台借钱才勉强推进。这套房子价格高达1000多万,有钱买却没钱装修!...
  3. 从高铁事故到软件系统的可靠性
  4. python: c_char_p指向的bitmap图像数据,通过c_char_Array最终赋值给PIL的Image对象
  5. 手动修改网卡接口模式从网桥变为路由
  6. ISE 14.7安装教程最新版(Win10安装)——解决Win10安装完后打不开快捷方式的方法
  7. Java将弃用finalize()方法?
  8. Stormpath发布了简化移动和前端身份验证的客户端API
  9. Opengl-基本概念-纹理(单纯的颜色太单调弄张图显示不是更好)
  10. 谈谈我对服务熔断、服务降级的理解 专题
  11. 【PAT乙级】1037 在霍格沃茨找零钱 (20 分)
  12. matlab 点云特征_基于点云的3D障碍物检测
  13. centos7全盘备份到本地_CentOS7下制作openssl1.1.1i RPM包并升级
  14. mysql去重取最大值,逻辑类似oracle的over(partition by)函数
  15. 计算机维修与护理论文,计算机维修与维护方面论文选题 计算机维修与维护论文题目怎样定...
  16. 列表显示新闻等信息,添加新消息图标
  17. Nginx基础详细讲解
  18. 软件质量属性:易用性
  19. 均衡发展计算机教室解说词,均衡发展图书室解说词|小学图书室解说词开场白范文推荐...
  20. 计算机 澳洲 博士后 要考雅思么,博士后移民澳大利亚(澳洲做科研博士后)

热门文章

  1. 显微镜下的大明内容_平凡故事展现炮火下人性光辉,李少红《解放·终局营救》创作全解...
  2. SpringBoot 使用 Caffeine 本地缓存
  3. 小程序 获取腾讯地图计算两经纬度的实际距离(可批量)_多地打卡
  4. Zookeeper UI管理界面安装
  5. linux 环境安装DBI和DBD_03
  6. 查看大日志文件的专门工具logviewer
  7. Linux环境安装并配置Maven
  8. linux搭建SonarQube_Oracle
  9. Java-用IDEA创建Java项目
  10. php依赖注入解决什么问题,php – 了解依赖注入的问题