Java:静态嵌套类和反射:"$"vs"."

Jas*_*n S 11 java reflection nested-class

如果我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());
    }
}
Run Code Online (Sandbox Code Playgroud)

澄清:我正在寻找一种在实际应用中处理这个问题的好方法(不仅仅是上面提到的测试用例),或者:

一个.使用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,则有效输入,以及包含Enum2内部类的com/example/Test.java.

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

Jas*_*n S 9

阿格:我应该只是用Class.getName()而不是Class.getCanonicalName().


Jon*_*eet 5

好吧,getCanonicalName国家的文件:

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

(强调我的.)

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

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