黑马程序员技术交流社区

标题: 为什么枚举类构造器无法通过反射得到? [打印本页]

作者: lixiuliang    时间: 2014-3-4 12:21
标题: 为什么枚举类构造器无法通过反射得到?
                Constructor enumCon = Enum.class.getDeclaredConstructor(null);
                //报NoSuchMethodException
作者: hauntedlove    时间: 2014-3-4 13:37
你在创建枚举时,编译器为你生成了一个类,该类继承自java.lang.Enum。
所以,Enum.class的值是class java.lang.Enum,即系统的枚举类,这个类首先是没有空参数的构造器的,
以下取自JDK 1.6的源码:
这个是枚举类的构造器,
protected Enum(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }
上面的注释“ Sole constructor.  Programmers cannot invoke this constructor.”
这句话的意思是,唯一的构造器,程序员不能获取这个构造器。
invoke这个词,你应该很熟悉了,是反射里很重要的方法。
枚举的“构造器”是为了给有参数的枚举值赋值用的,它和一般类的构造器是有区别的,枚举类是无法创建对象的,也是不能从枚举继承子类的,所以,枚举类所谓的“构造器”其实不是一般意义的构造器。
作者: lixiuliang    时间: 2014-3-5 12:02
hauntedlove 发表于 2014-3-4 13:37
你在创建枚举时,编译器为你生成了一个类,该类继承自java.lang.Enum。
所以,Enum.class的值是class java. ...

我得出最终答案来了,反射MyEnum.class.getDeclaredConstructor(String.class,int.class);会报
Cannot reflectively create enum objects
枚举只实例化一次,第二次创建实例起,就会抵御反射攻击
以下是单例模式抵御暴力反射的方法:
  1. class Single{
  2.        
  3.         private static int count = 0;
  4.        
  5.         private Single(){
  6.                 if(count == 1){
  7.                         throw new RuntimeException("只能初始化一次!");
  8.                 }
  9.                 count++;
  10.         }
  11.        
  12.         private static Single instance = new Single();
  13.        
  14.         public static Single getInstance(){
  15.                 return instance;
  16.         }
  17.        
  18. }
复制代码





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2