我看JAVA 之 枚举类型

简介: 我看JAVA 之 枚举类型 注:基于jdk11 Enum Enum是Java(1.5+)中所有枚举类型的公共基类。有关枚举的更多信息,包括编译器合成的隐式声明方法的描述,可以在Java™语言规范的第8.9节中找到。

我看JAVA 之 枚举类型

注:基于jdk11

Enum

Enum是Java(1.5+)中所有枚举类型的公共基类。有关枚举的更多信息,包括编译器合成的隐式声明方法的描述,可以在Java™语言规范的
[第8.9节](https://docs.oracle.com/javase/specs/jls/se11/html/jls-8.html#jls-8.9)中找到。
当使用枚举类型作为Set中的元素或Map中的key时,可以使用专用且高效的java.util.EnumSetjava.util.EnumMap实现。

定义一个枚举类,隐式继承了java.lang.Enum类(所以枚举类只能去实现接口不能显式继承其他类),见如下代码块:
enum Color {//
   RED, GREEN, BLANK, YELLOW
}

实现了如下几个接口

1. Comparable
2. Serializable

源码分析:

public abstract class Enum<E extends Enum<E>>
    implements Comparable<E>, Serializable {
/**
 * accessing this field.枚举常量名称,访问名称时,最好使用toString()方法而不是直接访问name字段。
 */
private final String name;

/**
 * 枚举常量名称,访问名称时,最好使用toString()方法而不是此方法。
 */
public final String name() {
    return name;
}

/**
 * 枚举常量在枚举类中定义的次序,次序从0开始。开发人员很少用到这个字段。此字典被设计用来在基于枚举类型的复杂数据结构中,如 java.util.EnumSet 和 java.util.EnumMap。
 *
 */
private final int ordinal;

public final int ordinal() {
    return ordinal;
}

/**
 * Sole constructor.  Programmers cannot invoke this constructor.
 * It is for use by code emitted by the compiler in response to
 * enum type declarations.
 * 唯一的构造器。开发人员不能调用这个构造函数。它由编译器调用以响应枚举类型的声明。
 */
protected Enum(String name, int ordinal) {
    this.name = name;
    this.ordinal = ordinal;
}

/**
 * 默认返回枚举常量的名字,此方法可以被覆盖以便返回更加友好name。
 *
 * @return the name of this enum constant
 */
public String toString() {
    return name;
}

/**
 * Returns true if the specified object is equal to this
 * enum constant.
 *
 * @param other the object to be compared for equality with this object.
 * @return  true if the specified object is equal to this
 *          enum constant.
 */
public final boolean equals(Object other) {
    return this==other;
}

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

/**
 * 枚举类型不可以克隆,以保持其单例性。
 * @return (never returns)
 */
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;
}

/**
 * 返回枚举常量对应的类对象。如果两个枚举常量调用getDeclaringClass()值相等,name这两个枚举对象的枚举类型相同。
 */
@SuppressWarnings("unchecked")
public final Class<E> getDeclaringClass() {
    Class<?> clazz = getClass();
    Class<?> zuper = clazz.getSuperclass();
    return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
}

/**
 * 返回指定枚举类型和名称的枚举常量。参数name一定要与指定枚举类型的常量名称相同(多余的空白字符也是不被允许的)。
 */
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()
 */
@SuppressWarnings("deprecation")
protected final void finalize() { }

/**
 * prevent default deserialization
 */
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");
}
}

适用原则

枚举在什么地方适用呢?一条普遍规则是,任何使用常量的地方,例如目前用 switch 代码切换常量的地方。如果只有单独一个值(例如,鞋的最大尺寸,或者笼子中能装猴子的最大数目),则还是把这个任务留给常量吧。但是,如果定义了一组值,而这些值中的任何一个都可以用于特定的数据类型,那么将枚举用在这个地方最适合不过。

例子:

    package chapter03;

    public class TestEnum {
        public static void main(String [] args) {
            System.out.println(Color.RED);
            System.out.println(Color.RED.name());
            System.out.println(Color.RED.ordinal());
            System.out.println(Color.class);
            System.out.println(Color.class.isEnum());

            System.out.println(Color.RED.getDeclaringClass());

            System.out.println("--- Class.getEnumConstants() ---");
            for (Color color: Color.RED.getClass().getEnumConstants()) {
                System.out.println(color);
            }

            System.out.println("--- interface enhance ---");
            System.out.println(Color.RED.info());

            System.out.println("--- switch clause ---");
            System.out.println(swithColor(Color.RED));

            System.out.println("--- Enum.valueOf() ---");
            System.out.println(Enum.valueOf(Color.class, "YELLOW"));
            System.out.println(Enum.valueOf(Color.class, " YELLOW"));
        }

        public static Color swithColor(Color color) {
            switch (color) {
                case RED : return Color.GREEN;
                case GREEN : return Color.YELLOW;
                case YELLOW : return Color.RED;
                default: return Color.GREEN;
            }

        }
    }
    interface ColorInterface {
        String info();
    }
    enum Color implements ColorInterface{
       RED, GREEN, YELLOW;

        @Override
        public String info() {
            return name() + "'s info";
        }
    }

打印结果如下:

    RED
    RED
    0
    class chapter03.Color
    true
    class chapter03.Color
    --- Class.getEnumConstants() ---
    RED
    GREEN
    YELLOW
    --- interface enhance ---
    RED's info
    --- switch clause ---
    GREEN
    --- Enum.valueOf() ---
    YELLOW
    Exception in thread "main" java.lang.IllegalArgumentException: No enum constant chapter03.Color. 
        at java.base/java.lang.Enum.valueOf(Enum.java:240)
        at chapter03.TestEnum.main(TestEnum.java:21)
相关文章
|
11天前
|
安全 Java 测试技术
🎉Java零基础:全面解析枚举的强大功能
【10月更文挑战第19天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
97 60
|
2月前
|
安全 Java 索引
Java——反射&枚举
本文介绍了Java反射机制及其应用,包括获取Class对象、构造方法、成员变量和成员方法。反射允许在运行时动态操作类和对象,例如创建对象、调用方法和访问字段。文章详细解释了不同方法的使用方式及其注意事项,并展示了如何通过反射获取类的各种信息。此外,还介绍了枚举类型的特点和使用方法,包括枚举的构造方法及其在反射中的特殊处理。
60 9
Java——反射&枚举
|
2月前
|
Java
java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)
java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)
79 5
|
2月前
|
安全 Java 开发者
Java 枚举(enum)详解
Java 中的枚举(`enum`)是一种特殊的数据类型,用于定义一组固定的常量,提升代码的类型安全性和可读性。枚举使用 `enum` 关键字定义,支持方法和构造函数,具有类型安全、单例、自动序列化等特点,并且可以遍历和用于 `switch` 语句中。实际应用包括状态机、指令集、类型标识等场景。枚举使代码更加清晰易维护。
|
6月前
|
安全 Java 程序员
Java语言枚举(Enum)的深入探索
Java语言枚举(Enum)的深入探索
|
3月前
|
Java
Java枚举使用的基本案例
这篇文章是关于Java枚举的基本使用,通过一个指令下发的代码案例,展示了如何定义枚举、使用枚举以及如何通过枚举实现指令的匹配和处理。
|
3月前
|
Java 开发者
在Java编程中,if-else与switch作为核心的条件控制语句,各有千秋。if-else基于条件分支,适用于复杂逻辑;而switch则擅长处理枚举或固定选项列表,提供简洁高效的解决方案
在Java编程中,if-else与switch作为核心的条件控制语句,各有千秋。if-else基于条件分支,适用于复杂逻辑;而switch则擅长处理枚举或固定选项列表,提供简洁高效的解决方案。本文通过技术综述及示例代码,剖析两者在性能上的差异。if-else具有短路特性,但条件增多时JVM会优化提升性能;switch则利用跳转表机制,在处理大量固定选项时表现出色。通过实验对比可见,switch在重复case值处理上通常更快。尽管如此,选择时还需兼顾代码的可读性和维护性。理解这些细节有助于开发者编写出既高效又优雅的Java代码。
47 2
|
3月前
|
安全 Java 编译器
|
4月前
|
存储 缓存 Java
java枚举消除冗余代码问题之findByName和findByValue方法工作时的问题如何解决
java枚举消除冗余代码问题之findByName和findByValue方法工作时的问题如何解决
|
4月前
|
安全 Java
Java进阶之枚举
【7月更文挑战第11天】Java枚举是Java 5引入的特性,用于定义固定常量集合,如星期。枚举是继承自`java.lang.Enum`的特殊类,编译后成为final类,每个枚举值是静态final实例。定义枚举用`enum`关键字,如`public enum Weekday {MONDAY, TUESDAY, ...}`。枚举可包含方法和变量,能实现接口但不能继承其他类。例如,`Weekday`枚举可实现`Describe`接口,提供`describe()`方法。在实际应用中,枚举常用于表示如响应状态等固定选项,便于类型安全和代码阅读。
39 8