Java: статические вложенные классы и отражение: «$» против «.»

Если у меня есть класс com.example.test.Enum2.Test как в код ниже, почему getCanonicalName () возвращает com.example.test.Enum2.Test , но для Class.forName () требуется "com.example .test.Enum2 $ Test " в качестве аргумента?

Есть ли способ обеспечить согласованность, чтобы я мог сериализовать / десериализовать значение перечисления по его имени, без необходимости проверять каждое $ ] против . возможность, когда перечисление является вложенным классом?

package com.example.test;

import java.util.Arrays;

public class Enum2 {

    enum Test {
        FOO, BAR, BAZ;
    }

    public static void main(String[] args) {
        for (String className : Arrays.asList(
                "com.example.test.Enum2.Test",
                "com.example.test.Enum2$Test"))
        {
            try {
                Class<?> cl = Class.forName(className);
                System.out.println(className+" found: "+cl.getCanonicalName());
            }
            catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

        System.out.println(Test.FOO.getDeclaringClass().getCanonicalName());
    }
}

пояснение: I ' m ищет хороший способ справиться с этой проблемой в реальном приложении (а не только в надуманном выше тестовом примере), либо:

a. сериализуйте / десериализуйте, используя вывод getCanonicalName () (только имя с точками), а для Class.forName () попробуйте каждую возможность по очереди, например, first "com.example. test.Enum2.Test «, затем « com.example.test.Enum2 $ Test », затем « com.example.test $ Enum2 $ Test » и т. д.

б. используйте правильную нотацию $, чтобы Class.forName () работал правильно с первого раза. Но для этого мне необходимо реализовать альтернативу getCanonicalName (), которая создает строку, совместимую с Class.forName () .

Я склоняюсь к подходу (b), частично из интуиции, и частично потому, что подход (a) имеет двусмысленность, если есть имена пакетов с заглавными буквами: com.example.Test.Enum2 и com.example.Test $ Enum2 могут быть допустимыми входными данными для Class.forName () если есть com / example / Test / Enum2.java и com / example / Test.java, содержащий внутренний класс Enum2.

... но я не знаю, как это реализовать. Есть идеи?

11
задан vaxquis 21 May 2015 в 10:40
поделиться