1

メソッドが定義されていない Java の enum と、メソッドが定義されている enum との奇妙な動作の違いに遭遇しました。後者の場合、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)

メソッドを持つ列挙型に対して 2 つのクラスが作成されるのはなぜですか? のインスタンス化中にこれが問題を引き起こすのはなぜEnumMapですか? コンパイル時に正確な列挙型を知らずにインスタンスを作成するには、どうすればこれを回避できますか?

4

2 に答える 2

0

複数のクラスがある理由は、あたかも inline を宣言したかのように、値ごとenumに匿名の内部クラス ( ) を作成することによって、さまざまなメソッドが実装されるためです。「回避策」は、その列挙型の値のクラスではなく、実際のクラス ( ) を使用することです。を安全に使用するのに十分な情報を知っている場合は、の「ネイティブ」タイプを使用するのに十分な情報を知っていることになります。$1enumActionListenerenumTestEnumWithMethodEnumMapenum

于 2013-09-13T08:56:29.590 に答える