Java:静态嵌套类和反射:“$”vs“。”

时间:2011-02-09 18:21:13

标签: java reflection nested-class

如果我有以下代码中的课程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。

...但我不知道如何实现它。有什么想法吗?

2 个答案:

答案 0 :(得分:9)

ARGH:我应该只使用Class.getName()代替Class.getCanonicalName()

答案 1 :(得分:5)

嗯,getCanonicalName州的文档:

  

返回Java语言规范定义的基础类的规范名称。

(强调我的。)

在Java中语言,嵌套用点表示。就库和VM而言,嵌套类只是一个名称为$的类。

你还没有说过你正在谈论什么样的序列化 - 只要你对两个方向都是一致的,那就应该没问题了。