写点什么

深入浅出 Java 中枚举的实现原理

  • 2021 年 12 月 14 日
  • 本文字数:1947 字

    阅读完需:约 6 分钟

作者:幻好

来源:恒生LIGHT云社区


Java 中的枚举— Enum 的全称为 Enumeration, 在 JDK 1.5 时就引入的特性,通过 java.lang 包中调用。

基本概述

在 JDK1.5 之前,通过定义常量使用的都是:public static fianl。而枚举的设计,就是把相关的常量分组到一个枚举类型里,方便创建和管理。


比如我们要定义一个颜色常量:


public enum Colour {    RED, YELLOW, BLUE, GREEN}
复制代码


这段代码通过底层编译后,实际创建了 4 个枚举对象:


new Enum<EnumTest>("RED", 0);new Enum<EnumTest>("YELLOW", 1);new Enum<EnumTest>("BLUE", 2);new Enum<EnumTest>("GREEN", 3);
复制代码

使用方式

条件选择

enum 能通过 switch 方法进行简单条件判断


Colour color = Colour.RED;switch (color) {    case RED:        System.out.println("红色");        break;    case YELLOW:        System.out.println("黄色");        break;    case GREEN:        System.out.println("绿色");        break;    case BLUE:        System.out.println("蓝色");        break;    default:        System.out.println(color);        break;}
复制代码

循环遍历

通过循环遍历 .values() 能够取到对象中的值


for (Colour e : Colour.values()) {    System.out.println(e.toString());}
复制代码

集合映射

在我们使用枚举类型作为集合的类型或映射中的键的类型时,可以使用专门且高效的集合和映射实现。如: java.util.EnumSetjava.util.EnumMap


// EnumSet的使用EnumSet<Colour> colorSet = EnumSet.allOf(Colour.class);for (Colour color : colorSet) {    System.out.println(color);}
// EnumMap的使用EnumMap<Colour, String> colorMap = new EnumMap(Colour.class);colorMap.put(Colour.RED, "红色");colorMap.put(Colour.YELLOW, "黄色");colorMap.put(Colour.GREEN, "绿色");colorMap.put(Colour.BLUE, "蓝色");
Set<Map.Entry<Colour, String>> colorEntries = colorMap.entrySet();for (Map.Entry<Colour, String> entry : colorEntries) { System.out.println(entry.getKey().name() + ":" + entry.getValue());}
复制代码

常用方法

通过 java.lang.Enum 类的源码,可以探索下枚举常用的一些方法和设计思想:


public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {
复制代码


// Enum 唯一的构造函数,由于 protected 修饰,所以不能调用这个构造函数。 它供编译器为响应枚举类型声明而发出的代码使用。protected Enum(String name, int ordinal) {    this.name = name;    this.ordinal = ordinal;}
复制代码


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


// 返回此枚举常量的序数(它在枚举声明中的位置,其中初始常量被分配零序数)。(但大多数程序员不会使用这种方法)public final int ordinal() {    return ordinal;}
复制代码


    // 与指定的对象进行比较以进行排序,当此对象小于、等于或大于指定对象时,返回一个负整数、零或正整数。且只能与相同枚举类型的其他枚举常量进行比较。     public final int compareTo(E o) {        Enum<?> other = (Enum<?>)o;        Enum<E> self = this;        if (self.getClass() != other.getClass()             self.getDeclaringClass() != other.getDeclaringClass())            throw new ClassCastException();        return self.ordinal - other.ordinal;    }
复制代码


// 返回与此枚举常量的枚举类型对应的 Class 对象。public final Class<E> getDeclaringClass() {    Class<?> clazz = getClass();    Class<?> zuper = clazz.getSuperclass();    return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;}
复制代码



}
复制代码

底层原理

enum 的语法结构可能对于正常的 Java 看起来怪怪的,但是通过编译器编译后产生的是一个 .class 文件, 可以理解枚举的语法结构是一种规范,使编译器能识别并转化为相应的类,底层实际上还是 class


public class com.project.demo.Colour extends java.lang.Enum{    public static final com.project.demo.Colour RED;    public static final com.project.demo.Colour YELLOW;    public static final com.project.demo.Colour BLUE;    public static final com.project.demo.Colour GREEN;    static {};}
复制代码

总结

所以 enum 实际上在 Java 只是一个类的形式存在,它能够更加方便的帮助我们定义常量对象,并且支持定义属性和方法,在一定程度上提高了我们的编程效率。


但是在使用时需要注意, enum 不能支持继承,应该它已经继承了包里的 java.lang.Enum 类,所以在程序设计时我们需要考虑到。

发布于: 2021 年 12 月 14 日阅读数: 21
用户头像

还未添加个人签名 2018.11.07 加入

还未添加个人简介

评论

发布
暂无评论
深入浅出 Java 中枚举的实现原理