Java:静态嵌套类和反射:“$”vs“。”
如果我有一个类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"
等
b。使用适当的$符号,以便Class.forName()
第一次正常工作。但是这需要我实现getCanonicalName()的替代方法,该方法会生成一个与Class.forName()
一致的字符串。
我倾向于方法(b),部分来自直觉,部分原因是方法(a)在包名大写的情况下有歧义:com.example.Test.Enum2和com.example.Test $如果存在com/example/Test/Enum2.java和包含Enum2内部类的com/example/Test.java,则Enum2都可以是有效的输入,即Class.forName()
。
...但我不知道如何实现它。有任何想法吗?
ARGH:我应该只是简单地使用Class.getName()
而不是Class.getCanonicalName()
。
那么,对于getCanonicalName
状态的文档:
返回由Java语言规范定义基础类的规范名称。
(重点煤矿。)
在Java语言,嵌套表示以点。就图书馆和虚拟机而言,嵌套类只是名称中带有$的类。
你还没有说过你在谈论什么样的序列化 - 只要你对这两个方向一致,它应该没问题。
无赖。所以语言的名字!= VM的名字。 :-(是否有一种更简单的方法将虚线符号转换为正确的$,而不必依次尝试每种可能性(例如com.example.test.Enum2.Test,com.example.test.Enum2 $ Test,com .example.test $ Enum2 $ Test等等) – 2011-02-09 18:49:17