枚舉類是Java5新添加的一種類型,其本質也是一個類,既然是類,怎麼不會讓實例化,不然本身的那幾個實例怎麼得來的
枚舉類並非堅不可摧,我們可以通過下面的代碼,繞過構造方法newInstance時,對枚舉類的檢查,注意是用反射,直接拿到ConstructorAccessor進行實例化
public enum MyEnum {
D;
public static void main(String[] args) throws Exception {
Constructor c = MyEnum.D.getClass().getDeclaredConstructors()[0];
Method acquireConstructorAccessor = Constructor.class.getDeclaredMethod("acquireConstructorAccessor");
acquireConstructorAccessor.setAccessible(true);
acquireConstructorAccessor.invoke(c);
Field field = Constructor.class.getDeclaredField("constructorAccessor");
field.setAccessible(true);
ConstructorAccessor constructorAccessor = (ConstructorAccessor) field.get(c);
MyEnum a = (MyEnum) constructorAccessor.newInstance(new Object[]{"CCCC", 2});
System.out.println(a);
}
}
既然如此,那麼用枚舉實現單例模式也是有漏洞的哦!!!
以上代碼在JDK9+無法運行,因爲JDK1.9之後對類的訪問權限(包括反射)設置了更安全的控制