枚举_源码_分析

news/2025/1/13 10:59:18/

枚举源码分析

前言

这是所有Java语言枚举类型的公共基类。关于枚举的更多信息,包括编译器合成的隐式声明方法的描述,可以在Java的第8.9节中找到™ 语言规范。
请注意,当使用枚举类型作为集合的类型或映射中键的类型时,可以使用专门且高效的集合和映射实现

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

属性

第一个属性

在枚举声明中声明的此枚举常量的名称。大多数程序员应该使用toString方法,而不是访问这个字段。

 private final String name;

对应的方法

返回此枚举常量的名称,与在其枚举声明中声明的名称完全相同。大多数程序员应该优先使用toString方法,因为toString方法可能会返回一个更用户友好的名称。这种方法主要设计用于特殊情况,在这种情况下,正确性取决于获得确切的名称,而不同版本的名称不会有所不同。

    public final String name() {return name;}

第二个属性

此枚举常量的序数(它在枚举声明中的位置,其中初始常量被分配了一个序数0)。大多数程序员对这个不了解。它是为复杂的基于枚举的数据结构设计的,如java.util.EnumSet和java.util.EnumMap。

    private final int ordinal;

对应的方法

返回此枚举常量的序号(其在枚举声明中的位置,其中初始常量被分配了一个序号0)。大多数程序员对这个不了解。它是为复杂的基于枚举的数据结构设计的,如java.util.EnumSet和java.util.EnumMap。
返回值:这个枚举常量的序数

    public final int ordinal() {return ordinal;}

构造器

独有的构造器。程序员无法调用此构造函数。它由编译器在响应枚举类型声明时发出的代码使用

protected Enum(String name, int ordinal) {this.name = name;this.ordinal = ordinal;}

方法

toString

返回声明中包含的此枚举常量的名称。此方法可能会被重写,尽管它通常不是必需的或所需的。当存在更“友好”的字符串形式时,枚举类型应该覆盖此方法。
返回值:此枚举常量的名称

   public String toString() {return name;}

equals

形参:other–要与此对象进行相等比较的对象。
返回值:如果指定的对象等于此枚举常量,则为true 否则为false

    public final boolean equals(Object other) {return this==other;}

hashCode

返回此枚举常量的哈希代码

    public final int hashCode() {return super.hashCode();}

clone

抛出 CloneNotSupportedException。这保证了枚举永远不会被克隆,这对于保持其“singleton”状态是必要的。

    protected final Object clone() throws CloneNotSupportedException {throw new CloneNotSupportedException();}

compareTo

将此枚举与指定的对象进行顺序比较。返回负整数、零或正整数,因为此对象小于、等于或大于指定的对象。

注意枚举常量只能与相同枚举类型的其他枚举常量进行比较。此方法实现的自然顺序是常量声明的顺序。

 public final int compareTo(E o) {Enum<?> other = (Enum<?>)o;Enum<E> self = this;if (self.getClass() != other.getClass() && // optimizationself.getDeclaringClass() != other.getDeclaringClass())throw new ClassCastException();return self.ordinal - other.ordinal;}

getDeclaringClass

返回与此枚举常量的枚举类型对应的Class对象。当且仅当e1.getDeclaringClass()==e2.getDeclaring()时,两个枚举常量e1和e2具有相同的枚举类型。(对于具有常量特定类体的枚举常量,该方法返回的值可能与Object.getClass方法返回的数值不同。)

    @SuppressWarnings("unchecked")public final Class<E> getDeclaringClass() {Class<?> clazz = getClass();Class<?> zuper = clazz.getSuperclass();return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;}

valueOf

返回具有指定名称的指定枚举类型的枚举常量。名称必须与用于声明此类型中的枚举常量的标识符完全匹配。(不允许使用外部空白字符。)
请注意,对于特定的枚举类型T,可以使用该枚举上隐式声明 {@code public static T valueOf(String)}方法代x替此方法来从名称映射到相应的枚举常量。枚举类型的所有常量都可以通过调用该类型的隐式的公共静态 {@code public static T[] values()} 方法来获得

形参:

​ enumType–要从中返回常量的枚举类型的Class对象

​ name–要返回的常量的名称

返回值

​ 具有指定名称的指定枚举类型的枚举常量

抛出:

IllegalArgumentException–如果指定的枚举类型没有具有指定名称的常量,或者指定的类对象不表示枚举类型

NullPointerException–如果enumType或name为null

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

finalize

枚举类不能具有finalize方法

protected final void finalize() { }

readObject

防止默认反序列化

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

从上面可以分析出

  1. 禁止枚举子类的泛型定义

image.png

image.png

image.png

注意将父类修改为枚举类后它由编译器在响应枚举类型声明时发出的代码使用

image.png

这个就证明了不能泛型定义因为没有构造器

唯一有的构造器还是独有的构造器它由编译器在响应枚举类型声明时发出的代码使用

  1. Enum类无法被继承
public class testEnum extends Enum{
}
public class testEnum extends Enum<Enum<E>>{
}
public class testEnum<E> extends Enum<Enum<E>>{
}

编译器转义之后

public final class Color extends Enum<Color> {public static final Color[] values() { return (Color[])VALUES.clone(); }public static Color valueOf(String name) { ... }private Color(String s, int i) { super(s, i); }public static final Color RED;public static final Color BLUE;public static final Color GREEN;private static final ColorVALUES[];static {RED = new Color("RED", 0);BLUE = new Color("BLUE", 1);GREEN = new Color("GREEN", 2);$VALUES = (new Color[] { RED, BLUE, GREEN });}
} 

当我们使用enum关键字定义一个枚举的时候,他会帮我们在编译后默认继承java.lang.Enum类,而不像其他的类一样默认继承Object类。且采用enum声明后,该类会被编译器加上final声明,故该类是无法继承的

  1. 抽象类不能被实例化

在java程序中不能使用new关键字来声明一个Enum,如果想要定义可以使用这样的语法:

enum  T1{value1,value2method1(){}method2(){}
}

http://www.ppmy.cn/news/103721.html

相关文章

Java Spring概述

文章目录 1、Spring是什么&#xff1f;2、Spring 的狭义和广义3、Spring Framework特点4、Spring模块组成5、Spring6版本要求 1、Spring是什么&#xff1f; Spring 是一款主流的 Java EE 轻量级开源框架 &#xff0c;Spring 由“Spring 之父”Rod Johnson 提出并创立&#xff…

推荐一波免费的ChatGPT镜像,助力开发,事半功倍!

目录 核桃 andisearch 小杰AI zw7 AI万能助手 核桃 ​​​​​​​https://chat.jubianxingqiu.com/ 这个网站的使用和回答都是快速和准确的&#xff0c;只要提问的问题越具体&#xff0c;回答的答案就会更精准。而且这个网站还有一个好处就是不用充值也能用&#xff…

Java 集合、数组、字符串的相互转换(关于list.toArray(new String[0])的源码分析)

在 Java 中&#xff0c;可以通过以下方式实现集合、数组和字符串之间的相互转换。 一、集合和数组的相互转化 ①、将集合转为数组&#xff1a;&#xff08;toArray 方法&#xff09; List<String> list new ArrayList<>(); list.add("apple"); lis…

七个合法学习黑客技术的网站,让你从萌新成为大佬

合法的学习网站&#xff0c;以下这些网站&#xff0c;虽说不上全方位的满足你的需求&#xff0c;但是大部分也都能。能带你了解到黑客有关的技术&#xff0c;视频&#xff0c;电子书&#xff0c;实践&#xff0c;工具&#xff0c;数据库等等相关学习内容。以上这些网站我都是用…

在 AWS EC2 Linux 服务器上部署Gunicorn

在 AWS EC2 Linux 服务器上部署 Flask 应用的步骤类似&#xff0c;你也可以使用 Gunicorn。以下是具体步骤&#xff1a; 1. 连接到你的 AWS EC2 实例。你可以通过 SSH 进行连接&#xff0c;如&#xff1a; ssh -i /path/to/your/key.pem ec2-useryour-ec2-ip-address 2. 在你…

如何优化Vue应用程序的性能?如何使用Webpack进行打包和优化?

嘿&#xff0c;Vue开发者们&#xff0c;你们想让自己的应用程序跑得更快吗&#xff1f;没问题&#xff0c;我可以给你们一些优化建议&#xff01; 首先&#xff0c;我们可以使用Vue.js提供的异步组件来加快应用程序的加载速度。异步组件可以在需要时才加载&#xff0c;而不是在…

MySQL分库分表方案及sharding-spher(2)

六、分库分表总结 在数据库设计时候考虑垂直分库和垂直分表 随着数据库数据量增加&#xff0c;不要马上考虑做水平切分&#xff0c;首先考虑缓存处理&#xff0c;读写分离&#xff0c;使用索引等等方式&#xff0c;如果这些方式不能根本解决问题了&#xff0c;再考虑做水平分…

编程练习【找出数组的最大公约数】

给你一个整数数组 nums &#xff0c;返回数组中最大数和最小数的 最大公约数 。 两个数的 最大公约数 是能够被两个数整除的最大正整数。 示例 1&#xff1a; 输入&#xff1a;nums [2,5,6,9,10] 输出&#xff1a;2 解释&#xff1a; nums 中最小的数是 2 nums 中最大的数是 …