Javaでクラス名を取得する
1. 概要
このチュートリアルでは、Class APIのメソッドからクラスの名前を取得する4つの方法、getSimpleName(), getName(), getTypeName()とgetCanonicalName(). について学習します。
これらのメソッドは、類似した名前とやや曖昧なJavadocのために混乱を招く可能性があります。 また、プリミティブ型、オブジェクト型、内部クラスまたは匿名クラス、および配列に関しては、微妙な違いがあります。
2. 単純名の取得
getSimpleName()メソッドから始めましょう。
Javaには、simpleとqualifiedの2種類の名前があります。 A simple name consists of a unique identifier while a qualified name is a sequence of simple names separated by dots.
その名前が示すように、getSimpleName()は、基になるクラスの単純な名前、つまりthe name it has been given in the source codeを返します。
次のクラスを想像してみましょう。
package com.example.className;
public class RetrieveClassName {}
その単純な名前はRetrieveClassNameになります。
assertEquals("RetrieveClassName", RetrieveClassName.class.getSimpleName());
プリミティブ型と配列の単純な名前を取得することもできます。 int, booleanやfloatのように、単に名前になるプリミティブ型の場合。
また、配列の場合、メソッドはthe simple name of the type of the array followed by a pair opening and closing brackets for each dimension of the array ([])を返します。
RetrieveClassName[] names = new RetrieveClassName[];
assertEquals("RetrieveClassName[]", names.getClass().getSimpleName());
したがって、2次元のString配列の場合、そのクラスでgetSimpleName()を呼び出すと、String[][]が返されます。
最後に、匿名クラスの特定のケースがあります。 Calling getSimpleName() on an anonymous class will return an empty string.
3. 他の名前を取得する
次に、クラスの名前、タイプ名、または正規名を取得する方法を見てみましょう。 getSimpleName()とは異なり、これらの名前はクラスに関するより多くの情報を提供することを目的としています。
getCanonicalName()メソッドは、常に正規名as defined in the Java Language Specification.を返します
他の方法については、ユースケースに応じて出力が少し異なる場合があります。 これがさまざまなプリミティブタイプとオブジェクトタイプにとって何を意味するかを見ていきます。
3.1. プリミティブ型
プリミティブ型は単純なので、まず始めましょう。 For primitive types, all three methods getName(), getTypeName() and getCanonicalName() will return the same result as getSimpleName():
assertEquals("int", int.class.getName());
assertEquals("int", int.class.getTypeName());
assertEquals("int", int.class.getCanonicalName());
3.2. オブジェクトタイプ
これらのメソッドがオブジェクトタイプでどのように機能するかを見ていきます。 それらの動作は一般的に同じです:they all return the canonical name of the class。
ほとんどの場合、これはすべてのクラスパッケージの単純名とクラスの単純名を含む修飾名です。
assertEquals("com.example.className.RetrieveClassName", RetrieveClassName.class.getName());
assertEquals("com.example.className.RetrieveClassName", RetrieveClassName.class.getTypeName());
assertEquals("com.example.className.RetrieveClassName", RetrieveClassName.class.getSimpleName());
3.3. 内部クラス
前のセクションで見たのは、これらのメソッド呼び出しの一般的な動作ですが、いくつかの例外があります。
内部クラスもその1つです。 getName() およびgetTypeName()メソッドは、内部クラスのgetCanonicalName()メソッドとは動作が異なります。
getCanonicalName() still returns the canonical name of the class、つまり、囲んでいるクラスの正規名と、ドットで区切られた内部クラスの単純な名前です。
一方、getName() メソッドとgetTypeName()メソッドはほとんど同じですが、use a dollar as the separator between the enclosing class canonical name and the inner class simple nameを返します。
RetrieveClassNameの内部クラスInnerClassを想像してみましょう。
public class RetrieveClassName {
public class InnerClass {}
}
次に、各呼び出しは、少し異なる方法で内部クラスを示します。
assertEquals("com.example.RetrieveClassName.InnerClass",
RetrieveClassName.InnerClass.class.getCanonicalName());
assertEquals("com.example.RetrieveClassName$InnerClass",
RetrieveClassName.InnerClass.class.getName());
assertEquals("com.example.RetrieveClassName$InnerClass",
RetrieveClassName.InnerClass.class.getTypeName());
3.4. 匿名クラス
匿名クラスも別の例外です。
すでに見てきたように、単純な名前はありませんが、they also don’t have a canonical nameです。 したがって、getCanonicalName()は何も返しません。 In opposition to getSimpleName(), getCanonicalName() will return nullであり、匿名クラスで呼び出された場合は空の文字列ではありません。
getName()とgetTypeName()については、calling class canonical name followed by a dollar and a number representing the position of the anonymous class among all anonymous classes created in the calling classを返します。
これを例を挙げて説明しましょう。 ここで2つの匿名クラスを作成し、最初のクラスでgetName()を呼び出し、2番目のクラスでgetTypeName() を呼び出し、それらをcom.example.Mainで宣言します。
assertEquals("com.example.Main$1", new RetrieveClassName() {}.getClass().getName());
assertEquals("com.example.Main$2", new RetrieveClassName() {}.getClass().getTypeName());
2番目の呼び出しは、2番目の匿名クラスに適用されるため、末尾に番号が増加した名前が返されることに注意してください。
3.5. 配列
最後に、上記の3つの方法で配列がどのように処理されるかを見てみましょう。
配列を扱っていることを示すために、各メソッドは標準の結果を更新します。 The getTypeName() and getCanonicalName() methods will append pairs of brackets to their result.
2次元のInnerClass配列でgetTypeName() とgetCanonicalName()を呼び出す次の例を見てみましょう。
assertEquals("com.example.RetrieveClassName$InnerClass[][]",
RetrieveClassName.InnerClass[][].class.getTypeName());
assertEquals("com.example.RetrieveClassName.InnerClass[][]",
RetrieveClassName.InnerClass[][].class.getCanonicalName());
最初の呼び出しで、ドットではなくドルを使用して、内部クラス部分を残りの名前から分離する方法に注意してください。
getName()メソッドがどのように機能するかを見てみましょう。 プリミティブ型の配列で呼び出されると、an opening bracket and a letter representing the primitive type。 が返されます。次の例で、2次元のプリミティブ整数配列でそのメソッドを呼び出すことを確認しましょう。
assertEquals("[[I", int[][].class.getName());
一方、オブジェクト配列で呼び出されると、add an opening bracket and the L letter to its standard result and finish with a semi-colonになります。 RetrieveClassNameの配列で試してみましょう。
assertEquals("[Lcom.example.className.RetrieveClassName;", RetrieveClassName[].class.getName());
4. 結論
この記事では、Javaでクラス名にアクセスするための4つのメソッドを検討しました。 これらのメソッドは、getSimpleName(), getName(), getTypeName()とgetCanonicalName()です。
最初のクラスはクラスのソースコード名を返すだけで、他のクラスはパッケージ名やクラスが内部クラスであるか匿名クラスであるかなどの詳細情報を提供することを学びました。
この記事のコードはover on GitHubにあります。