枚举的本质

枚举的本质

  • 枚举本质是一个类,使用设计模式中的单例模式,但是不可以被反射创建
public enum EnumDeep {
  APPLE("红", 19.23),
  ORANGE("橙红", 200.01);
  EnumDeep(String color, double money) {}
}

很简单的一个枚举类

  • Constructor源码中newInstance方法调用newInstanceWithCaller方法,如果是枚举就会抛出异常
@CallerSensitive
@ForceInline // to ensure Reflection.getCallerClass optimization
public T newInstance(Object ... initargs)
    throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException
{
    Class<?> caller = override ? null : Reflection.getCallerClass();
    return newInstanceWithCaller(initargs, !override, caller);
}


T newInstanceWithCaller(Object[] args, boolean checkAccess, Class<?> caller)
    throws InstantiationException, IllegalAccessException,
InvocationTargetException
{
    if (checkAccess)
        checkAccess(caller, clazz, clazz, modifiers);

    if ((clazz.getModifiers() & Modifier.ENUM) != 0)
        throw new IllegalArgumentException("Cannot reflectively create enum objects");

    ConstructorAccessor ca = constructorAccessor;   // read volatile
    if (ca == null) {
        ca = acquireConstructorAccessor();
    }
    @SuppressWarnings("unchecked")
    T inst = (T) ca.newInstance(args);
    return inst;
}

为了保证单例模式的安全性。

反射创建枚举抛出异常

Constructor<?>[] c = EnumDeep.class.getDeclaredConstructors();
for (Constructor<?> constructor : c) {
    System.out.println(constructor);
    constructor.setAccessible(true); // 允许访问private
    constructor.newInstance();
}

// 报错: Cannot reflectively create enum objects

与上面Constructor源码报错信息一致。所以枚举类是单例模式最安全的,不会被反射破解,我们自己写的DCL懒汉模式会被反射破解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值