对于带有方法的枚举,无法使用动态类参数实例化EnumMap

时间:2013-09-13 08:40:21

标签: java class enums runtime enum-map

我偶然发现Java中枚举之间的行为奇怪,没有任何已定义的方法和那些:在后一种情况下,Enum.classEnum.getClass()实际上引用了不同的编译类,即{{ 1}};这在试图例如使用仅在运行时指定的类实例化!Enum.class.equals(Enum.getClass())

EnumMap

相应的控制台输出是:

import java.util.EnumMap;

public class EnumMapTest {

    private enum TestEnum {
        FOO;
    }

    private enum TestEnumWithMethod {
        BAR {
            @Override
            protected void doSomething() {
            }
        };

        protected abstract void doSomething();
    }

    public static void main(String[] args) {
        System.out.println(String.format("Testing enum %s...", TestEnum.class));

        final Class<TestEnum> enumStaticClass = TestEnum.class;
        System.out.println(String.format("EnumMap construction using static %s...", enumStaticClass));
        new EnumMap<TestEnum, Object>(enumStaticClass);

        final Class<TestEnum> enumDynamicClass = (Class<TestEnum>) TestEnum.FOO.getClass();
        System.out.println("Are the static and dynamic classes equal? " + enumStaticClass.equals(enumDynamicClass));
        System.out.println(String.format("EnumMap construction using dynamic %s...", enumDynamicClass));
        new EnumMap<TestEnum, Object>(enumDynamicClass);


        System.out.println(String.format("Testing enum %s...", TestEnumWithMethod.class));

        final Class<TestEnumWithMethod> enumWithMethodStaticClass = TestEnumWithMethod.class;
        System.out.println(String.format("EnumMap construction using static %s...", enumWithMethodStaticClass));
        new EnumMap<TestEnumWithMethod, Object>(enumWithMethodStaticClass);

        final Class<TestEnumWithMethod> enumWithMethodDynamicClass = (Class<TestEnumWithMethod>) TestEnumWithMethod.BAR.getClass();
        System.out.println("Are the static and dynamic classes equal? " + enumWithMethodStaticClass.equals(enumWithMethodDynamicClass));
        System.out.println(String.format("EnumMap construction using dynamic %s...", enumWithMethodDynamicClass));
        new EnumMap<TestEnumWithMethod, Object>(enumWithMethodDynamicClass);
    }
}

为什么有两个类用于枚举方法?为什么这会在Testing enum class EnumMapTest$TestEnum... EnumMap construction using static class EnumMapTest$TestEnum... Are the static and dynamic classes equal? true EnumMap construction using dynamic class EnumMapTest$TestEnum... Testing enum class EnumMapTest$TestEnumWithMethod... EnumMap construction using static class EnumMapTest$TestEnumWithMethod... Are the static and dynamic classes equal? false EnumMap construction using dynamic class EnumMapTest$TestEnumWithMethod$1... Exception in thread "main" java.lang.NullPointerException at java.util.EnumMap.initialization(EnumMap.java:726) at java.util.EnumMap.<init>(EnumMap.java:395) at EnumMapTest.main(EnumMapTest.java:46) 实例化期间导致问题?如何在编译时不知道确切的枚举类型的情况下创建实例?

2 个答案:

答案 0 :(得分:0)

多个类的原因是通过为每个enum值创建一个匿名内部类($1)来实现不同的enum方法,就好像你是声明了一些内联ActionListener。 “解决方法”是使用实际的enum类(TestEnumWithMethod),而不是该枚举值的类;如果您了解足够的信息以安全使用EnumMap,您就会知道足够的信息来使用enum的“原生”类型。

答案 1 :(得分:0)

我发现了问题:Enum.getClass()获取特定枚举实例的匿名类,例如FOOBAR,而Enum.getDeclaringClass()获取实际枚举的类。奇怪的是后者仍然无法使用方法,但是......