11

以下のコードのようなクラスがある場合、引数として返されるのに必要なの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());
    }
}

明確化:実際のアプリケーションでこの問題を処理する良い方法を探しています (上記の不自然なテスト ケースだけではありません)。

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 がある場合の有効な入力。

...しかし、私はそれを実装する方法がわかりません。何か案は?

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 に答える