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

发布于 2024-10-16 13:14:33 字数 1745 浏览 0 评论 0原文

如果我有一个 com.example.test.Enum2.Test 类,如下面的代码所示,为什么 getCanonicalName() 返回 com.example.test.Enum2 .TestClass.forName() 需要 "com.example.test.Enum2$Test" 作为参数?

有没有办法保持一致,以便我可以通过名称序列化/反序列化枚举值,而无需检查每个 $. 可能性,当枚举为嵌套类?

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$Enum2 都可以是如果存在 com/example/Test/Enum2.java 和包含 Enum2 内部类的 com/example/Test.java,则为 Class.forName() 的有效输入。

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

If I have a class com.example.test.Enum2.Test as in the code below, why does getCanonicalName() return com.example.test.Enum2.Test but Class.forName() requires "com.example.test.Enum2$Test" as an argument?

Is there a way to be consistent, so that I can serialize/deserialize an enum value by its name, without having to check each $ vs . possibility, when the enum is a nested class?

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());
    }
}

clarification: I'm looking for a good way to deal with this problem in a real application (not just the above contrived test case), either:

a. serialize/deserialize using getCanonicalName()'s output (dotted name only), and for Class.forName() try each possibility in turn e.g. first "com.example.test.Enum2.Test", then "com.example.test.Enum2$Test", then "com.example.test$Enum2$Test", etc.

b. use proper $ notation, so that Class.forName() works right the first time. But this requires me to implement an alternative to getCanonicalName() that produces a string that is consistent with Class.forName().

I am leaning toward approach (b), partially from gut feel, and partially because approach (a) has ambiguities if there are package names with capital letters: com.example.Test.Enum2 and com.example.Test$Enum2 can both be valid inputs to Class.forName() if there is a com/example/Test/Enum2.java, and a com/example/Test.java containing an Enum2 inner class.

...but I don't know how to implement it. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

那一片橙海, 2024-10-23 13:14:33

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

ARGH: I should have been simply using Class.getName() instead of Class.getCanonicalName().

剩余の解释 2024-10-23 13:14:33

好吧, getCanonicalName 的文档指出:

返回由 Java 语言规范定义的底层类的规范名称。

(强调我的。)

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

您还没有说您正在谈论哪种序列化 - 只要两个方向保持一致,就应该没问题。

Well, the docs for getCanonicalName state:

Returns the canonical name of the underlying class as defined by the Java Language Specification.

(Emphasis mine.)

In Java the language, nesting is indicated with a dot. As far as libraries and the VM are concerned, the nested class is just a class with a $ in the name.

You haven't said what kind of serialization you're talking about - so long as you're consistent for both directions, it should be fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文