リフレクションでのEnum継承クラスのコンストラクタ
enumキーワードで宣言されるEnum継承クラス(ここではE)のコンストラクタは、リフレクションで調べると…
package test; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class EnumConstructorTest { private enum E { A, ; // 無引数に見える private E(){/**/} private E(final Number num){/**/} private E(final Number num1, final Number num2){/**/} } public static void main(final String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { Constructor<?>[] ctrs = E.class.getDeclaredConstructors(); for (Constructor<?> ctr : ctrs) { // E(String, int) など System.out.println(ctr); } Constructor<E> ctr = E.class.getDeclaredConstructor(String.class, int.class); ctr.setAccessible(true); ctr.newInstance("hoge", 1); } }
privateコンストラクタを定義しても先頭にString, int引数が付加される。
setAccessibleして呼び出すとIllegalArgumentExceptionが発生する。
実行結果
private test.EnumConstructorTest$E(java.lang.String,int,java.lang.Number) private test.EnumConstructorTest$E(java.lang.String,int) private test.EnumConstructorTest$E(java.lang.String,int,java.lang.Number,java.lang.Number) Exception in thread "main" java.lang.IllegalArgumentException: Cannot reflectively create enum objects at java.lang.reflect.Constructor.newInstance(Unknown Source) at test.EnumConstructorTest.main(EnumConstructorTest.java:28)
なお、E(String, int) ではなくスーパークラスのコンストラクタEnum(String, int) を呼ぶとInstantiationExceptionが発生する。これはEnumがabstractだから。