jdk源码分析--Enum

1 篇文章 0 订阅
1 篇文章 0 订阅
enum可以定义枚举值,我们通过public enum TestEnum{...}  这样的语句定义一个枚举类型。enum是java的一个保留字,我们似乎没有找到enum的实现代码。不过我们可以通过反编译一个自己定义的枚举类型窥其一斑。
public enum TestEnum {
    ONE("one", "1");

    private String code;
    private String name;

    TestEnum(String code, String name) {
        this.code = code;
        this.name = name;
    }
}
这样一个自定义的枚举类型,经过反编译之后得到:
public final class TestEnum extends java.lang.Enum<TestEnum> {
  public static final TestEnum ONE;
  public static TestEnum[] values();
  public static TestEnum valueOf(java.lang.String);
  static {};
}
可以看到枚举值的实现方式是一个继承了Enum类型的final类,其中枚举对象都是内部定义的final枚举对象。
源码位置:java.lang.Enum
Enum是一个抽象类,类定义:
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {...}
其范型类型是其子类,也就是自己定义的枚举类型。
数据结构
name:用于保存定义的枚举常量的名称,也就是上面例子中的ONE
ordinal: 枚举常量的序数,跟定义时的顺序有关。
方法分析
枚举类中值得探究的方法不是很多,大概看一下:
构造函数:仅有的一个构造函数,使用者无法调用,编译器生成枚举声明的代码时会用到这个构造函数。
valueof方法:根据范型类型和名称获得这个枚举的实例。实际通过Class类中的方法获取枚举值:enumType.enumConstantDirectory().get(name); 其中enumType是Class类型的对象,name是枚举对象的名称。

Class类中维护了一个枚举名称和实例变量的map:private volatile transient Map<String, T> enumConstantDirectory = null;如果这个类是一个枚举类型,那么在枚举类第一次访问valueof方法时,会生成这个map。
Map<String, T> enumConstantDirectory() {
        if (enumConstantDirectory == null) {
            T[] universe = getEnumConstantsShared();
            if (universe == null)
                throw new IllegalArgumentException(
                    getName() + " is not an enum type");
            Map<String, T> m = new HashMap<>(2 * universe.length);
            for (T constant : universe)
                m.put(((Enum<?>)constant).name(), constant);
            enumConstantDirectory = m;
        }
        return enumConstantDirectory;
    }
枚举类型的Class时如何获得保存的枚举值的?Class维护了一个枚举类型的数组:private volatile transient T[] enumConstants = null;然后通过调用枚举类中的values方法,将枚举数据赋值给这个变量。
T[] getEnumConstantsShared() {
        if (enumConstants == null) {
            if (!isEnum()) return null;
            try {
                final Method values = getMethod("values");
                java.security.AccessController.doPrivileged(
                    new java.security.PrivilegedAction<Void>() {
                        public Void run() {
                                values.setAccessible(true);
                                return null;
                            }
                        });
                @SuppressWarnings("unchecked")
                T[] temporaryConstants = (T[])values.invoke(null);
                enumConstants = temporaryConstants;
            }
            // These can happen when users concoct enum-like classes
            // that don't comply with the enum spec.
            catch (InvocationTargetException | NoSuchMethodException |
                   IllegalAccessException ex) { return null; }
        }
        return enumConstants;
    }
通过枚举类型生成的values方法,可以获得所有的枚举值。查看反编译代码可以看到枚举类中会生成一个values方法。
静态方法invoke参数为null
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值