Javaでクラス名を取得する

1.概要

このチュートリアルでは、 Class APIのメソッドからクラスの名前を取得するための4つの方法について学習します。 ()[getSimpleName()]、https://docs.oracle.com/javase/10/docs/api/java/lang/Class.html#getName()[getName()]、https://docs.oracle .com/javase/10/docs/api/java/lang/Class.html#getTypeName() および getCanonicalName() 。 __

これらのメソッドは、名前が似ていてJavadocがややあいまいなため、混乱を招く可能性があります。プリミティブ型、オブジェクト型、内部クラスまたは匿名クラス、および配列に関しても、いくつかの微妙な違いがあります。

2.簡単な名前を取得する

getSimpleName() メソッドから始めましょう。

Javaでは、 simple qualified の2種類の名前があります。単純名は一意の識別子で構成され、修飾名はドットで区切られた一連の単純名です。

その名前が示すように、 getSimpleName() は基礎となるクラスの単純な名前、つまり ソースコードで与えられた名前 を返します。

次のようなクラスを想像してみましょう。

package com.baeldung.className;
public class RetrieveClassName {}

その単純な名前は RetrieveClassName になります。

assertEquals("RetrieveClassName", RetrieveClassName.class.getSimpleName());

プリミティブ型と配列の単純な名前も取得できます。 int、boolean 、または float のような単純な名前になるプリミティブ型の場合。

そして配列の場合、このメソッドは** 配列の型の単純な名前とそれに続く配列の各次元の開始括弧と終了括弧([])を返します。

RetrieveClassName[]names = new RetrieveClassName[];
assertEquals("RetrieveClassName[]", names.getClass().getSimpleName());

したがって、2次元の String 配列の場合、そのクラスで getSimpleName() を呼び出すと、 String[][] が返されます。

最後に、無名クラスの特定のケースがあります。

無名クラスで getSimpleName() を呼び出すと、空の文字列が返されます。

3.他の名前を取得する

それでは、クラスの名前、型名、または正規名を取得する方法を見てみましょう。 getSimpleName() とは異なり、これらの名前はクラスに関する詳細情報を提供することを目的としています。

getCanonicalName() メソッドは、https://docs.oracle.com/javase/specs/jls/se11/html/jls-6.html#jls-6.7[Java言語仕様]で定義されている標準名 を常に返します。 。

他の方法に関しては、ユースケースによって出力が少し異なる場合があります。プリミティブやオブジェクトの種類が異なるとどうなるかわかります。

3.1. プリミティブ型

単純なプリミティブ型から始めましょう。 プリミティブ型の場合、3つのすべてのメソッド getName()、getTypeName() 、および getCanonicalName() は、 getSimpleName() と同じ結果を返します。

assertEquals("int", int.class.getName());
assertEquals("int", int.class.getTypeName());
assertEquals("int", int.class.getCanonicalName());

3.2. オブジェクトタイプ

これらのメソッドがオブジェクト型とどのように連携するのかがわかります。それらの振る舞いは一般的に同じです: それらはすべてクラスの正規名を返します

ほとんどの場合、これはクラスの単純名だけでなく、すべてのクラスパッケージの単純名も含む修飾名です。

assertEquals("com.baeldung.className.RetrieveClassName", RetrieveClassName.class.getName());
assertEquals("com.baeldung.className.RetrieveClassName", RetrieveClassName.class.getTypeName());
assertEquals("com.baeldung.className.RetrieveClassName", RetrieveClassName.class.getSimpleName());

3.3. 内部クラス

前のセクションで見たことはこれらのメソッド呼び出しの一般的な振る舞いですが、いくつかの例外があります。

内部クラスもその1つです。

__getName() および getTypeName() メソッドは、内部クラスの getCanonicalName()__メソッドとは動作が異なります。

  • getCanonicalName() は、クラスの正規名** を返します。つまり、それを囲むクラスの正規名と、ドットで区切られた内部クラスの単純名です。

一方、 __getName() および getTypeName()__メソッドはほとんど同じを返しますが、囲むクラスの正規名と内部クラスの単純名の間の区切り文字としてドルを使用します。

RetrieveClassName の内部クラス InnerClass を想像してみましょう。

public class RetrieveClassName {
    public class InnerClass {}
}

それから、各呼び出しは少し異なる方法で内部クラスを表します。

assertEquals("com.baeldung.RetrieveClassName.InnerClass",
  RetrieveClassName.InnerClass.class.getCanonicalName());
assertEquals("com.baeldung.RetrieveClassName$InnerClass",
  RetrieveClassName.InnerClass.class.getName());
assertEquals("com.baeldung.RetrieveClassName$InnerClass",
  RetrieveClassName.InnerClass.class.getTypeName());

3.4. 無名クラス

無名クラスは別の例外です。

すでに見たように、彼らは単純な名前を持っていませんが、 彼らはまた正式な名前を持っていません 。したがって、 getCanonicalName() は何も返しません。 getSimpleName() とは反対に、 getCanonicalName() は、無名クラスで呼び出されたときに null を返し、空の文字列は返しません。

getName() getTypeName() については、呼び出しクラスで作成されたすべての匿名クラスの中で、呼び出しクラスの正規名にドルと匿名クラスの位置を表す数字が続く** が返されます。

例を挙げて説明しましょう。ここでは2つの無名クラスを作成し、最初のクラスで getName() を呼び出し、2番目のクラスで __getTypeName() を呼び出して、 com.baeldung.Main で宣言します。

assertEquals("com.baeldung.Main$1", new RetrieveClassName() {}.getClass().getName());
assertEquals("com.baeldung.Main$2", new RetrieveClassName() {}.getClass().getTypeName());

2番目の匿名クラスに適用されているように、2番目の呼び出しでは末尾の数字が増えた名前が返されることに注意してください。

3.5. 配列

最後に、上記の3つの方法で配列がどのように処理されるのかを見てみましょう。

配列を扱っていることを示すために、各メソッドはその標準結果を更新します。 ** getTypeName() メソッドと getCanonicalName() メソッドは、結果に括弧のペアを追加します。

次の例を見てみましょう。ここでは、2次元の InnerClass 配列に対して __getTypeName() および getCanonicalName()__を呼び出します。

assertEquals("com.baeldung.RetrieveClassName$InnerClass[][]",
  RetrieveClassName.InnerClass[][].class.getTypeName());
assertEquals("com.baeldung.RetrieveClassName.InnerClass[][]",
  RetrieveClassName.InnerClass[][].class.getCanonicalName());

最初の呼び出しがドットの代わりにドルを使用して、内部クラス部分とそれ以外の名前を区別する方法に注意してください。

それでは、 getName() メソッドの仕組みを見てみましょう。プリミティブ型の配列で呼び出されると、開き括弧とhttps://docs.oracle.com/javase/10/docs/api/java/lang/Class.html#getName()を表す文字が返されます。次の例で、2次元のプリミティブ整数配列でそのメソッドを呼び出していることを確認しましょう。

assertEquals("[[I", int[][].class.getName());

一方、オブジェクト配列で呼び出されると、標準結果に左大括弧とL文字を追加し、セミコロンで終了します。 RetrieveClassName の配列で試してみましょう。

assertEquals("[Lcom.baeldung.className.RetrieveClassName;", RetrieveClassName[].class.getName());

4.まとめ

この記事では、Javaでクラス名にアクセスするための4つの方法を調べました。これらのメソッドは、 getSimpleName()、getName()、getTypeName() 、および getCanonicalName() です。

最初のものはクラスのソースコード名を返すだけで、他のものはパッケージ名やクラスが内部クラスか匿名クラスかなどの詳細情報を提供することがわかりました。

この記事のコードはhttps://github.com/eugenp/tutorials/tree/master/core-java-lang[over on GitHub]にあります。