如果我有以下代码中的课程com.example.test.Enum2.Test
,为什么getCanonicalName()
会返回com.example.test.Enum2.Test
,但Class.forName()
需要"com.example.test.Enum2$Test"
作为参数?
是否有一种方法可以保持一致,以便我可以按名称序列化/反序列化枚举值,而不必检查每个$
vs .
的可能性,当枚举是嵌套类时?
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());
}
}
澄清:我正在寻找一种在实际应用中处理这个问题的好方法(不仅仅是上面提到的测试用例):
一个。使用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如果有com / example / Test / Enum2.java,则可以是Class.forName()
的有效输入,以及包含Enum2内部类的com / example / Test.java。
...但我不知道如何实现它。有什么想法吗?
答案 0 :(得分:9)
ARGH:我应该只使用Class.getName()
代替Class.getCanonicalName()
。
答案 1 :(得分:5)
嗯,getCanonicalName
州的文档:
返回Java语言规范定义的基础类的规范名称。
(强调我的。)
在Java中语言,嵌套用点表示。就库和VM而言,嵌套类只是一个名称为$的类。
你还没有说过你正在谈论什么样的序列化 - 只要你对两个方向都是一致的,那就应该没问题了。