看 JDK
源码,进入Constructor
的newInstance()
方法中:
public T newInstance(Object... initargs) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
if (!this.override) {
Class<?> caller = Reflection.getCallerClass();
this.checkAccess(caller, this.clazz, this.clazz, this.modifiers);
}
if ((this.clazz.getModifiers() & 16384) != 0) {
throw new IllegalArgumentException("Cannot reflectively create enum objects");
} else {
ConstructorAccessor ca = this.constructorAccessor;
if (ca == null) {
ca = this.acquireConstructorAccessor();
}
T inst = ca.newInstance(initargs);
return inst;
}
}
原来,在源码中对枚举类型进行了强制性的判断(16384
代表枚举类型),如果是枚举类型,直接抛异常。到此为止也就说明了为什么《Effective Java》推荐使用枚举来实现单例的原因: JDK
枚举的语法特殊性,以及反射也为枚举保驾护航,让枚举式单例成为一种比较优雅的实现。
本文中所涉及的源码可在 github 上找到,相关的测试代码在 test 包下:https://github.com/eamonzzz/java-advanced