以下のコードのようなクラスがある場合、引数として返されるのに必要なのcom.example.test.Enum2.Test
はなぜですか?getCanonicalName()
com.example.test.Enum2.Test
Class.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());
}
}
明確化:実際のアプリケーションでこの問題を処理する良い方法を探しています (上記の不自然なテスト ケースだけではありません)。
a. 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 の両方が可能です。Class.forName()
com/example/Test/Enum2.java と、Enum2 内部クラスを含む com/example/Test.java がある場合の有効な入力。
...しかし、私はそれを実装する方法がわかりません。何か案は?