Если у меня есть класс 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.
... но я не знаю, как это реализовать. Есть идеи?