11

如果我有一个com.example.test.Enum2.Test如下代码中的类,为什么getCanonicalName()返回com.example.test.Enum2.TestClass.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()依次尝试每种可能性,例如 first "com.example.test.Enum2.Test"、 then "com.example.test.Enum2$Test"、 then"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 和包含 Enum2 内部类的 com/example/Test.java 的有效输入。

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

4

2 回答 2

9

ARGH:我应该简单地使用Class.getName()而不是Class.getCanonicalName().

于 2011-02-09T19:02:19.277 回答
5

好吧,getCanonicalName状态文档:

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

(强调我的。)

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

您还没有说您在谈论哪种序列化-只要您在两个方向上保持一致,就可以了。

于 2011-02-09T18:25:58.980 回答