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?
如果我有一个类com.example.test.Enum2。在下面的代码中测试,为什么getCanonicalName()返回com.example.test.Enum2。forname()要求“com.example.test”。Enum2美元这样测试”作为参数?
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?
是否有一种方法可以保持一致,以便我可以通过枚举值的名称来序列化/反序列化枚举值,而不必检查每个$ 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());
}
}
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.
使用getCanonicalName()的输出(仅用虚名)和Class.forName()的方式进行序列化/反序列化,并尝试每一种可能性,例如:first“com.example.test.Enum2”。测试”,那么“com.example.test。com . example。Enum2美元这样测试”,那么“测试Enum2测试”美元,这样美元等。
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()
.
b.使用适当的$表示法,使Class.forName()第一次正确工作。但是这需要我实现一个getCanonicalName()的替代方法,它产生一个与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.
我倾向于方法(b),部分来自于直觉,部分原因是方法(a)如果有大写字母的包名,就有歧义。com . example。Enum2和这样如果有一个com/example/Test/Enum2,那么Test$Enum2都可以是Class.forName()的有效输入。java和com/example/Test。包含枚举2内部类的java。
...but I don't know how to implement it. Any ideas?
…但是我不知道如何实现它。什么好主意吗?
2 个解决方案
#1
9
ARGH: I should have been simply using Class.getName()
instead of Class.getCanonicalName()
.
我应该简单地使用Class.getName()而不是Class.getCanonicalName()。
#2
5
Well, the docs for getCanonicalName
state:
好的,getCanonicalName状态的文档:
Returns the canonical name of the underlying class as defined by the Java Language Specification.
返回Java语言规范定义的底层类的规范名。
(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.
在Java语言中,嵌套用点表示。就库和VM而言,嵌套类只是一个名称中有$的类。
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.
您还没有说过您正在讨论的是哪种序列化——只要您在两个方向上都是一致的,就应该没问题。
#1
9
ARGH: I should have been simply using Class.getName()
instead of Class.getCanonicalName()
.
我应该简单地使用Class.getName()而不是Class.getCanonicalName()。
#2
5
Well, the docs for getCanonicalName
state:
好的,getCanonicalName状态的文档:
Returns the canonical name of the underlying class as defined by the Java Language Specification.
返回Java语言规范定义的底层类的规范名。
(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.
在Java语言中,嵌套用点表示。就库和VM而言,嵌套类只是一个名称中有$的类。
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.
您还没有说过您正在讨论的是哪种序列化——只要您在两个方向上都是一致的,就应该没问题。