Classオブジェクト(java.lang.Class)とは何ですか?


82

のJavaドキュメントはClass次のように述べています。

Classオブジェクトは、クラスがロードされるときにJava仮想マシンによって、およびdefineClassクラスローダーのメソッドの呼び出しによって自動的に構築されます。

これらのClassオブジェクトは何ですか?それらは、を呼び出すことによってクラスからインスタンス化されたオブジェクトと同じnewですか?

また、たとえば、継承していなくても、object.getClass().getName()どのようにしてすべてをスーパークラスClassにタイプキャストできますjava.lang.Classか?

回答:


97

にタイプキャストされるものはありませんClassObjectJavaのすべては特定のに属していclassます。そのため、Object他のすべてのクラスに継承されるクラスがgetClass()メソッドを定義します。

getClass()、またはclass-literal-クラスに関するメタデータを含むオブジェクトをFoo.class返しClassます。

  • 名前
  • パッケージ
  • メソッド
  • 田畑
  • コンストラクター
  • 注釈

鋳造と様々なチェックのようないくつかの便利なメソッド(isAbstract()isPrimitive()、など)。javadocは、クラスに関して取得できる情報を正確に示しています。

したがって、たとえば、自分のメソッドにオブジェクトが指定されていて、@Processableアノテーションが付けられている場合にそれを処理する場合は、次のようにします。

public void process(Object obj) {
    if (obj.getClass().isAnnotationPresent(Processable.class)) {
       // process somehow; 
    }
}

この例では、指定されたオブジェクトのクラス(それが何であれ)に関するメタデータを取得し、指定された注釈があるかどうかを確認します。Classインスタンスのメソッドの多くは、「リフレクティブ操作」または単に「リフレクション」と呼ばれます。リフレクション、その理由と時期については、こちらをご覧ください

Classオブジェクトは、実行中のJavaアプリケーションのクラスとともに列挙型とインターフェースを表し、それぞれのメタデータを持っていることにも注意してください。

要約すると、Javaの各オブジェクトにはクラス(に属している)があり、それぞれに Classがあり、実行時にアクセスできる、それに関するメタデータを含むオブジェクトがあります。


37
そして、これについてさらに考えるのは楽しいことです。Classクラス継承Objectそのもの。 クラスを表すオブジェクトをClass.class返します。あなたは反省について考えることができます。私の頭のASPLODE。ClassClass
cdhowie 2010

1
@pst:あります。人を傷つけたくなります。ルートタイプにこれほど多くのメソッドがある言語/フレームワークは埋めるに値します。これには、PHPスタイルのtack-random-crap-onto-the-API-without-any-forethoughtシンドロームがあります。炎キュー...
cdhowie

1
クラスc1 = Car.class; この「クラス」とは何ですか?それはすべてのクラスに存在するパブリック変数ですか?
デビッド・ブレイン2013

1
ある意味、そうです。実際、これは「クラスリテラル」です。これは、Classオブジェクトを名前で参照する方法です。
Bozho 2013

1
@cdhowieあなたのコメントは、私にとって「クラス」という言葉を意味的に満足させました。
stillanoob 2018

44

クラスオブジェクトは、オブジェクトのクラスを説明する一種のメタオブジェクトです。これは主にJavaのリフレクション機能で使用されます。実際のクラスの「青写真」のように考えることができます。たとえば、次のようなクラスの車があります。

public class Car {
    public String brand;
}

次に、「Car」クラスを記述するClassオブジェクトを作成できます。

Class myCarClass = Class.forName("Car");

これで、そのClassオブジェクトのCarクラスに対してあらゆる種類のクエリを実行できます。

myCarClass.getName() - returns "Car"
myCarClass.getDeclaredField("brand") - returns a Field object describing the "brand" field

等々。すべてのJavaオブジェクトには、Javaオブジェクトのクラスを記述するClassオブジェクトを返すメソッドgetClass()があります。したがって、次のようなことができます。

Car myCar = new Car();
Class myCarClass  = myCar.getClass();

これは、知らないオブジェクト、たとえば外部から取得したオブジェクトに対しても機能します。

public void tellMeWhatThisObjectsClassIs(Object obj) {
    System.out.println(obj.getClass().getName());
}

このメソッドに任意のJavaオブジェクトをフィードすると、指定したオブジェクトの実際のクラスが出力されます。

Javaを使用する場合、ほとんどの場合、Classオブジェクトについて心配する必要はありません。ただし、いくつかの便利なユースケースがあります。たとえば、特定のクラスのオブジェクトをプログラムでインスタンス化できます。これは、オブジェクトのシリアル化と逆シリアル化によく使用されます(たとえば、JavaオブジェクトをXMLまたはJSONとの間で変換します)。

Class myCarClass = Class.forName("Car");
Car myCar = myCarClass.newInstance();  // is roughly equivalent to = new Car();

また、これを使用して、クラスなどの宣言されたすべてのフィールドまたはメソッドを見つけることもできます。これは、特定の場合に非常に役立ちます。したがって、たとえば、メソッドが未知のオブジェクトを渡され、それについてもっと知る必要がある場合、たとえば、何らかのインターフェイスを実装する場合など、Classクラスはここでの友達です。

簡単に言うと、java.lang.reflectパッケージに含まれるClass、Field、Methodなどのクラスを使用すると、定義済みのクラス、メソッド、フィールドを分析し、それらの新しいインスタンスを作成し、メソッドを他のあらゆる種類のもので呼び出すことができます。また、実行時にこれを動的に実行できます。


1
クラスc1 = Car.class; この「クラス」とは何ですか?それはすべてのクラスに存在するパブリック変数ですか?
デビッド・ブレイン2013

5
基本的にはシンタックスシュガーです。これは、コンパイラが、指定された名前でクラスオブジェクトをロードするものに評価するものです。Class.forName( "完全修飾クラス名")とほぼ同等ですが、Class.forName()が実行時に実行される間、クラスはコンパイル時に存在することがチェックされます。
ヤントーマ

8

getClass()は、...のインスタンスであるオブジェクトを返すメソッドですjava.lang.Class。キャストは含まれていません。キャストは次のようになります。

Class<?> type = (Class<?>) object;

7

また、getClassが同じタイプのインスタンスに対して同じオブジェクトを返すというColinDの回答に追加したいと思います。これはtrueを出力します

    MyOtherClass foo = new MyOtherClass();
    MyOtherClass bar = new MyOtherClass();
    System.out.println(foo.getClass()==bar.getClass());

そうではないことに注意してくださいequals、私はを使用してい==ます。


3

Classオブジェクトは、Class(java.lang.Class)のインスタンスです。クラスのjavadocから取られた以下の引用はあなたの質問に答えるはずです

クラスにはパブリックコンストラクタがありません。代わりに、クラスオブジェクトは、クラスがロードされるときにJava仮想マシンによって、およびクラスローダーのdefineClassメソッドの呼び出しによって自動的に構築されます。


2

クラスオブジェクトを完全に理解するために、戻って、最初にクラスオブジェクトを取得することを理解しましょう。ご覧のとおり、.java作成するすべてのファイルをコンパイルすると.java、jvmが.classファイルを作成します。このファイルには、クラスに関するすべての情報が含まれています。

  1. クラスの完全修飾名
  2. クラスの親
  3. メソッド情報
  4. 可変フィールド
  5. コンストラクタ
  6. 修飾子情報
  7. 一定のプール

上に表示されるリストは、通常のクラスで通常表示されるものです。これまで、.javaファイルと.classファイルはハードディスクに存在します。実際にクラスを使用する必要がある場合、つまりmain()メソッドでコードを実行する必要がある場合、jvmはその.classファイルをハードドライブで使用し、5つのメモリのいずれかにロードします。.classメソッド領域であるjvmの領域は、ファイルをメソッド領域にロードした直後に、jvmはその情報と、ヒープメモリ領域に存在するそのクラスを表すClassオブジェクトを使用します。

これがトップレベルのビューです。

.java--compile-> .class->スクリプトを実行するとき->.classメソッド領域にロードします--jvmはメソッド領域からクラスオブジェクトを作成します->クラスオブジェクトが生まれます

クラスオブジェクトを使用すると、クラス名やメソッド名など、クラスに関するすべての情報を取得できます。

また、スクリプトで使用するクラスごとに1つのクラスオブジェクトのみが存在することにも注意してください。

これが理にかなっていることを願っています


良い追加ポイント。言い回しについての1つの注意点として、「jvmはその情報、ヒープメモリ領域に存在するそのクラス表すClassオブジェクトを使用する」という自分自身を編集するのが良いという主題はわかりません。正しくないように見えます。後で->の行がより論理的に見えます。私はここにいますか?一貫してください、ありがとう!
アレクセイMartianov

@Brendon Cheungが「そのクラスを表すClassオブジェクト」と言ったとき、それはクラスであり、そのクラスのインスタンスではないので、式を変更する必要があると思います。「インスタンス」のみがヒープメモリに入り、クラスではないためです。
starriet

1

Objectクラスは、デフォルトでJavaのすべてのクラスの親クラスです。言い換えれば、それはJavaの最上位クラスです。

Objectクラスは、タイプがわからないオブジェクトを参照する場合に役立ちます。親クラス参照変数は、アップキャストと呼ばれる子クラスオブジェクトを参照できることに注意してください。

例を見てみましょう。オブジェクトを返すgetObject()メソッドがありますが、Employee、Studentなどの任意のタイプにすることができ、Objectクラス参照を使用してそのオブジェクトを参照できます。例えば:

Object obj=getObject(); //このメソッドから返されるオブジェクトがわかりません

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.