Java クラスの正規名、単純名、クラス名の違いは何ですか? 質問する

Java クラスの正規名、単純名、クラス名の違いは何ですか? 質問する

Java では、次の違いは何ですか?

Object o1 = ....
o1.getClass().getSimpleName();
o1.getClass().getName();
o1.getClass().getCanonicalName();

Javadoc を何度も確認しましたが、それでも十分に説明されていません。また、テストも実行しましたが、これらのメソッドの呼び出し方法の背後にある実際の意味は反映されませんでした。

ベストアンサー1

何か不明な点がある場合は、まずテストを書いてみてください。

これは私がしました:

class ClassNameTest {
    public static void main(final String... arguments) {
        printNamesForClass(
            int.class,
            "int.class (primitive)");
        printNamesForClass(
            String.class,
            "String.class (ordinary class)");
        printNamesForClass(
            java.util.HashMap.SimpleEntry.class,
            "java.util.HashMap.SimpleEntry.class (nested class)");
        printNamesForClass(
            new java.io.Serializable(){}.getClass(),
            "new java.io.Serializable(){}.getClass() (anonymous inner class)");
    }

    private static void printNamesForClass(final Class<?> clazz, final String label) {
        System.out.println(label + ":");
        System.out.println("    getName():          " + clazz.getName());
        System.out.println("    getCanonicalName(): " + clazz.getCanonicalName());
        System.out.println("    getSimpleName():    " + clazz.getSimpleName());
        System.out.println("    getTypeName():      " + clazz.getTypeName()); // added in Java 8
        System.out.println();
    }
}

プリント:

int.class (primitive):
    getName():          int
    getCanonicalName(): int
    getSimpleName():    int
    getTypeName():      int

String.class (ordinary class):
    getName():          java.lang.String
    getCanonicalName(): java.lang.String
    getSimpleName():    String
    getTypeName():      java.lang.String

java.util.HashMap.SimpleEntry.class (nested class):
    getName():          java.util.AbstractMap$SimpleEntry
    getCanonicalName(): java.util.AbstractMap.SimpleEntry
    getSimpleName():    SimpleEntry
    getTypeName():      java.util.AbstractMap$SimpleEntry

new java.io.Serializable(){}.getClass() (anonymous inner class):
    getName():          ClassNameTest$1
    getCanonicalName(): null
    getSimpleName():    
    getTypeName():      ClassNameTest$1

最後のブロックには空のエントリがあり、getSimpleName空の文字列が返されます。

これを見ると、結論は次のようになります。

  • 名前、たとえば、Class.forNameデフォルトの を使用した の呼び出しなど、を使用してクラスを動的にロードするために使用する名前ですClassLoader。特定の のスコープ内ではClassLoader、すべてのクラスに一意の名前が付けられます。
  • 正規名は、インポート ステートメントで使用される名前です。これは、操作中toStringまたはロギング操作中に役立つ場合があります。javacコンパイラがクラスパスの完全なビューを持っている場合、コンパイル時に完全修飾クラス名とパッケージ名を衝突させることにより、クラスパス内の正規名の一意性を強制します。ただし、JVM はこのような名前の衝突を受け入れる必要があるため、正規名は 内のクラスを一意に識別しませんClassLoader。(後から考えると、このゲッターのより適切な名前は でしたがgetJavaName、このメソッドは、JVM が Java プログラムを実行するためだけに使用されていた時代のものです。)
  • 単純な名前はクラスを大まかに識別し、toString操作中またはログ記録中に役立つ可能性がありますが、一意であることが保証されません。
  • 型名「この型の名前に関する情報文字列」を返します。「それはtoString、純粋に情報提供のみであり、契約値はありません」。(sir4ur0n によって記述)

また、これらのタイプの技術的な Java API の詳細については、Java 言語仕様ドキュメントを参照することもできます。

Example 6.7-2.そしてExample 6.7-2.それぞれFully Qualified NamesFully Qualified Names v. Canonical Name

おすすめ記事