Если у меня есть класс 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());
}
}
уточнение: Я ищу хороший способ решения этой проблемы в реальном приложении (а не только в надуманном тестовом примере), либо:
a.сериализовать / десериализовать, используя вывод getCanonicalName()
(только пунктирное имя), и для Class.forName()
попробовать каждую возможность по очереди, например сначала "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.
... но я не знаю, как это реализовать.Есть идеи?