1

我偶然发现了Java中没有任何定义方法的枚举与那些定义了方法的枚举之间的奇怪行为差异:在后一种情况下,Enum.class实际上Enum.getClass()是指不同的编译类,即!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)

为什么使用方法为枚举创建两个类?为什么这会在实例化过程中引起问题EnumMap?在编译时不知道确切的枚举类型的情况下,如何解决这个问题来创建实例?

4

2 回答 2

0

多个类的原因是通过为每个值enum创建一个匿名内部类(the)来实现不同的方法,就像您声明了一些 inline 一样。“解决方法”是使用实际的类(),而不是该枚举值的类;如果您知道足够的信息来安全地使用,那么您就知道足够的信息来使用 的“本机”类型。$1enumActionListenerenumTestEnumWithMethodEnumMapenum

于 2013-09-13T08:56:29.590 回答
0

我发现了问题:Enum.getClass()获取特定枚举实例的匿名类,例如FOOor BAR,同时Enum.getDeclaringClass()获取实际枚举的类。奇怪的是后者仍然可以在没有方法的情况下工作,虽然......

于 2013-09-13T09:00:49.820 回答