关于枚举:深入浅出-Java-中枚举的实现原理

31次阅读

共计 2595 个字符,预计需要花费 7 分钟才能阅读完成。

根本概述

在 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.EnumSet、java.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 只是一个类的模式存在,java 培训它可能更加不便的帮忙咱们定义常量对象,并且反对定义属性和办法,在肯定水平上进步了咱们的编程效率。

然而在应用时须要留神,enum 不能反对继承,应该它曾经继承了包里的 java.lang.Enum 类,所以在程序设计时咱们须要思考到。

正文完
 0