java java.lang.enum_源码阅读-java基础-java.lang.Enum

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/531727.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java中有关线程的题目

1&#xff0c;看一下下面程序错误发生在哪一行&#xff01; class Test implements Runnable{public void run(Thread t){} }2&#xff0c;输出结果是什么&#xff1f; class Test{public static void main(String[] args){new Thread(new Runnable(){public void run(){System…

java 可逆的加密算法_java实现AES可逆加密算法

package com.hdu.encode;import javax.crypto.Cipher;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;/*** AES 是一种可逆加密算法&#xff0c;对用户的敏感信息加密处理 对…

森林转换成二叉树以及二叉树还原为森林代码

1 /*2 森林转换成二叉树3 思路&#xff1a;u的孩子节点为v1, v2, v3....&#xff08;v1,v2,....互为兄弟节点&#xff09; 4 那么将u的一个孩子节点&#xff08;v1&#xff09;连在u的左子树上&#xff0c;那么其他的孩子节点都连在v1的右子树上&#xff01; 5 …

poj1062昂贵的聘礼(Dijkstra**)

1 /*2 题意&#xff1a; 物主有一个物品&#xff0c;价值为P&#xff0c;地位为L&#xff0c; 以及一系列的替代品Ti和该替代品所对应的"优惠"Vi3 g[u][i] 表示的是u物品被i物品替换后的优惠价格&#xff01;(u>0, i>0)4 g[u][0]表示不用替换该物品的…

java openmp库_OpenMP的环境变量及库函数

OpenMP的环境变量&#xff1a;环境变量 描述 示例OMP_SCHEDULE 控制for循环任务分配结构的调度 OMP_SCHEDULE"guided,2"OMP_NUM_THREADS 设置默认线程的个数 OMP_SCHEDULE4OpenMP的库函数函数名称 描述int omp_get_num_threads(void) 返回当前使用的线程个数&#xf…

hdu1269迷宫城堡(判断有向图是否是一个强连通图)

1 /* 题意&#xff1a; 给你一个图&#xff0c;求这个有向图示否是一个强连通图&#xff08;每两个节点都是可以相互到达的&#xff09;&#xff01; 思路1&#xff1a;按正向边dfs一遍&#xff0c;将经过的节点计数&#xff0c;如果记录的节点的个数小于…

mgg mysql_mgg文件怎么转换mp3格式?

步骤/方法方法/步骤1:下载载视频转换器&#xff0c;我们说到在官网下载比较好吧。下载完成之后&#xff0c;我们就直接点击进行安装&#xff0c;一般 在安装的过程也是非常快速的&#xff0c;主要是按照安装向导上的步骤进行就可以了。方法/步骤2:安装好之后&#xff0c;我们就…

poj 2385Apple Catching(简单dp)

1 /*2 题意&#xff1a; 有两棵苹果树&#xff0c;每一棵苹果树每一秒间隔的掉落下来一个苹果&#xff0c;一个人在树下接住苹果&#xff0c;不让苹果掉落&#xff01;3 人在两棵树之间的移动是很快的&#xff01;但是这个人移动的次数是有限制的&#xff0c;问最多可以…

java dao 泛型的好处_java中泛型有什么作用

泛型的作用如下&#xff1a;1、类型安全泛型的主要目标是提高 Java 程序的类型安全。编译时的强类型检查&#xff1b;通过知道使用泛型定义的变量的类型限制&#xff0c;编译器可以在一个高得多的程度上验证类型假设。没有泛型&#xff0c;这些假设就只存在于程序员的头脑中(或…

poj3249Test for Job(记忆化搜索)

1 /*2 题意&#xff1a;给一个DAG图&#xff0c;n个节点&#xff0c;每个节点都对应一个值&#xff0c;入度为零的点走到出度为零的点&#xff0c;计算所有可能路径3 经过节点值的和最大&#xff01;4 5 思路&#xff1a;记忆话搜索&#xff1a;也就是如果我们搜索…

Java两同_java:一个类实现的两个接口里都有同一个方法(名),怎么处理?

不一定&#xff0c;关键要看子类是否是抽象类。如果子类是非抽象类&#xff0c;则必须实现接口中的所有方法&#xff1b;如果子类是抽象类&#xff0c;则可以不实现接口中的所有方法&#xff0c;因为抽象类中允许有抽象方法的存在&#xff01;1、抽象类定义抽象类往往用来表征对…

ZOJ3805Machine(二叉树左右子树变换)

1 /*2 题意&#xff1a;建立一棵二叉树&#xff0c;左子树和父节点占一个宽度&#xff0c;右子树另外占一个宽度&#xff01;3 使任意左右子树交换顺序&#xff0c;使得整个树的宽度最小&#xff01;4 思路&#xff1a;递归交换左右子树 &#xff01; …

java ==和=_Java ==和equals()的区别

前言本篇文章讲的是从JVM角度比较和equals的区别一&#xff1a;** Java数据类型分类**Paste_Image.png1&#xff1a;基本数据类型又称为原始数据类型&#xff0c;他们之间的比较应该使用()&#xff0c;比较的是他们的值。2&#xff1a;引用数据类型当引用数据类型用()进行比较&…

ZOJ 3804 YY's Minions (简单模拟)

1 /*2 题意&#xff1a;一个矩阵中有 n*m个宠物&#xff0c;每一个宠物都有一个状态&#xff0c; 1醒着的&#xff0c;0睡着的3 X离开的&#xff01;如果这个宠物&#xff08;醒着的&#xff09;的周围醒着的个数>3 || <2它就会睡着&#xff0c;4 如果这个宠物&…

java接口方法实现_Java接口的简单定义与实现方法示例

本文实例讲述了Java接口的简单定义与实现方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;1、接口是Java中最终要的概念&#xff0c;接口可以理解为一种特殊的类&#xff0c;里面全部是由全局常量和公共的抽象方法所组成。2、接口的格式:interface interfaceName{全…

NYOJ995硬币找零(简单dp)

1 /*2 题意&#xff1a;给你不同面额的硬币&#xff08;每种硬币无限多&#xff09;&#xff0c;需要找零的面值是T&#xff0c;用这些硬币进行找零&#xff0c;3 如果T恰好能被找零&#xff0c;输出最少需要的硬币的数目&#xff01;否则请输出剩下钱数最少的找零方案…

docker mysql命令大全_Docker命令大全

Docker run 命令docker run [OPTIONS] IMAGE [COMMAND] [ARG...]OPTIONS说明&#xff1a;-a stdin: 指定标准输入输出内容类型&#xff0c;可选 STDIN/STDOUT/STDERR 三项&#xff1b;-d: 后台运行容器&#xff0c;并返回容器ID&#xff1b;-i: 以交互模式运行容器&#xff0c;…

NYOJ 1023 还是回文(DP,花最少费用形成回文串)

1 /*2 题意&#xff1a;给出一串字符(全部是小写字母)&#xff0c;添加或删除一个字符&#xff0c;都会产生一定的花费。3 那么&#xff0c;将字符串变成回文串的最小花费是多少呢&#xff1f; 4 5 思路&#xff1a;如果一个字符串增加一个字符 x可以形成一个回文串…

java mapreduce教程_Java搭建MapReduce完成二次排序步骤

1、构建新的作业Configuration confgetConf();Job jobJob.getInstance(conf);job.setJarByClass(SortYearAndTemp2.class);2、设置输入输出目录Path inpathnew Path(conf.get("inpath"));Path outpathnew Path(conf.get("outpath"));FileInputFormat.addIn…

contentprovider java_创建Contentprovider,

创建Contentprovider:1. 创建一个provider----ExampleContentProvidera. 设计authority b. 设计path c.处理content URI IDs d.Content URI patterns)定义MIME Types(One of the required methods that you must implement for any provider.A method that youre expected to i…