JDK源码Enum类原理及代码实例解析

 更新时间:2020年11月16日 13:48  点击:1878

正文

一 概述

枚举类型是 JDK 5 之后引进的一种非常重要的引用类型,可以用来定义一系列枚举常量,使用 enum 来表示枚举可以更好地保证程序的类型安全和可读性

实际上在使用关键字enum创建枚举类型并编译后,编译器会为我们生成一个相关的类,这个类继承了Java API中的java.lang.Enum类,

也就是说通过关键字enum创建枚举类型在编译后事实上也是一个类类型而且该类继承自java.lang.Enum类

使用举例

public class EnumTest {

  enum MyCode{
    ONE("1","编码一"),
    TWO("2","编码二");

    private String code;
    private String name;

    MyCode(String code, String name) {
      this.code = code;
      this.name = name;
    }
  }

  public static void main(String[] args) {
    // 获取一个枚举实例
    MyCode one = MyCode.valueOf(MyCode.class, "ONE");
    // 可以调用Enum类中的实例方法
    one.compareTo(MyCode.TWO);
  }
}

二 源码分析

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

    //枚举常量的名称
    private final String name;

    //返回此枚举常量的名称,与其枚举声明中声明的完全相同
    public final String name() {
      return name;
    }

    //此枚举常量的序数(它在枚举声明中的位置,其中初始常量的序数为零)
    private final int ordinal;

    //返回序号
    public final int ordinal() {
      return ordinal;
    }

    // 构造器
    protected Enum(String name, int ordinal) {
      this.name = name;
      this.ordinal = ordinal;
    }

    //返回声明中包含的此枚举常量的名称
    public String toString() {
      return name;
    }

    //果指定的对象等于此枚举常量,则返回true。
    public final boolean equals(Object other) {
      return this==other;
    }

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

    // 无法被克隆
    protected final Object clone() throws CloneNotSupportedException {
      throw new CloneNotSupportedException();
    }

    //将此枚举与指定的枚举序号进行比较
    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;
    }

    //返回与此枚举常量的枚举类型相对应的Class对象
    @SuppressWarnings("unchecked")
    public final Class<E> getDeclaringClass() {
      Class<?> clazz = getClass();
      Class<?> zuper = clazz.getSuperclass();
      return (zuper == java.lang.Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
    }

    /**
     * 返回具有指定名称的指定枚举类型的枚举常量。
     * 该名称必须与用于声明此类型的枚举常量的标识符完全一致。
     * 请注意,对于特定枚举类型T ,
     * 有两个隐式声明方法可以直接使用:
     *   public static T valueOf(String)  根据名称获取单个枚举类型
     *   public static T[] values()  获取所有枚举类型数组
     */
    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 方法
    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");
    }
  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。

[!--infotagslink--]

相关文章

  • php svn操作类

    以前我们开发大型项目时都会用到svn来同步,因为开发产品的人过多,所以我们会利用软件来管理,今天发有一居然可以利用php来管理svn哦,好了看看吧。 代码如下 ...2016-11-25
  • PHP 数据库缓存Memcache操作类

    操作类就是把一些常用的一系列的数据库或相关操作写在一个类中,这样调用时我们只要调用类文件,如果要执行相关操作就直接调用类文件中的方法函数就可以实现了,下面整理了...2016-11-25
  • 源码分析系列之json_encode()如何转化一个对象

    这篇文章主要介绍了源码分析系列之json_encode()如何转化一个对象,对json_encode()感兴趣的同学,可以参考下...2021-04-22
  • JS+CSS实现分类动态选择及移动功能效果代码

    本文实例讲述了JS+CSS实现分类动态选择及移动功能效果代码。分享给大家供大家参考,具体如下:这是一个类似选项卡功能的选择插件,与普通的TAb区别是加入了动画效果,多用于商品类网站,用作商品分类功能,不过其它网站也可以用,...2015-10-21
  • Php文件上传类class.upload.php用法示例

    本文章来人大家介绍一个php文件上传类的使用方法,期望此实例对各位php入门者会有不小帮助哦。 简介 Class.upload.php是用于管理上传文件的php文件上传类, 它可以帮...2016-11-25
  • jQuery 2.0.3 源码分析之core(一)整体架构

    拜读一个开源框架,最想学到的就是设计的思想和实现的技巧。废话不多说,jquery这么多年了分析都写烂了,老早以前就拜读过,不过这几年都是做移动端,一直御用zepto, 最近抽出点时间把jquery又给扫一遍我也不会照本宣科的翻译...2014-05-31
  • PHP实现无限级分类(不使用递归)

    无限级分类在开发中经常使用,例如:部门结构、文章分类。无限级分类的难点在于“输出”和“查询”,例如 将文章分类输出为<ul>列表形式; 查找分类A下面所有分类包含的文章。1.实现原理 几种常见的实现方法,各有利弊。其中...2015-10-23
  • PHP实现递归无限级分类

    在一些复杂的系统中,要求对信息栏目进行无限级的分类,以增强系统的灵活性。那么PHP是如何实现无限级分类的呢?我们在本文中使用递归算法并结合mysql数据表实现无限级分类。 递归,简单的说就是一段程序代码的重复调用,当把...2015-10-23
  • mybatis-plus实体类主键策略有3种(小结)

    这篇文章主要介绍了mybatis-plus实体类主键策略有3种(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-08-27
  • ecshop商品无限级分类代码

    ecshop商品无限级分类代码 function cat_options($spec_cat_id, $arr) { static $cat_options = array(); if (isset($cat_options[$spec_cat_id]))...2016-11-25
  • C#类中static变量用法分析

    这篇文章主要介绍了C#类中static变量用法,实例分析了static变量使用技巧与相关注意事项,需要的朋友可以参考下...2020-06-25
  • PHP 一个完整的分页类(附源码)

    在php中要实现分页比起asp中要简单很多了,我们核心就是直接获取当前页面然后判断每页多少再到数据库中利用limit就可以实现分页查询了,下面我来详细介绍分页类实现程序...2016-11-25
  • c#各种Timer类的区别与用法介绍

    System.Threading.Timer 是一个简单的轻量计时器,它使用回调方法并由线程池线程提供服务。在必须更新用户界面的情况下,建议不要使用该计时器,因为它的回调不在用户界面线程上发生...2020-06-25
  • C#学习笔记整理_浅谈Math类的方法

    下面小编就为大家带来一篇C#学习笔记整理_浅谈Math类的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • 详解ES6实现类的私有变量的几种写法

    这篇文章主要介绍了详解ES6实现类的私有变量的几种写法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-10
  • ES5和ES6中类的区别总结

    这篇文章主要给大家介绍了ES5和ES6中类的区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-12-21
  • Java匿名内部类的写法示例

    这篇文章主要给大家介绍了关于Java匿名内部类的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-08-31
  • vue3源码剖析之简单实现方法

    源码的重要性相信不用再多说什么了吧,特别是用Vue 框架的,一般在面试的时候面试官多多少少都会考察源码层面的内容,下面这篇文章主要给大家介绍了关于vue3源码剖析之简单实现的相关资料,需要的朋友可以参考下...2021-09-07
  • php无限分类使用concat如何实现

    一、数据库设计 -- -- Table structure for table `category` -- CREATE TABLE `category` ( `id` int(11) NOT NULL auto_increment, `catpath` varchar(255) default NULL, `name` varchar(255) default NULL...2015-11-08
  • 适用于初学者的简易PHP文件上传类

    本文实例讲述了PHP多文件上传类,分享给大家供大家参考。具体如下:<&#63;phpclass Test_Upload{ protected $_uploaded = array(); protected $_destination; protected $_max = 1024000; protected $_messages =...2015-10-30