2-3-1:オブジェクトの情報を調べる


・ 「プログラム内のオブジェクトが何という名前のクラスに属するのか?」、 「そのオブジェクトにはどんなフィールドやメソッドが用意されているのか?」 こうしたことを調べたいとしましょう。 もちろんソースプログラムを見て知ることはできますが、 ここで考えているのはプログラマが調べるのではなく、 実行中のプログラムが動的にオブジェクトの情報を取得しようというケースです。 このような機能は通常のアプリケーションにとっては、常に必要なものではありません。 しかし Javaのシステム自身のように不特定多数のオブジェクトを管理したり、 新しいクラスの設計を行うための開発ツールなどでは必須となるはずです。 この「オブジェクトの情報を調べる」という機能を試してみることにしましょう。
 java.langには Class という名前のクラスが存在します(!)。 Class はクラスに関する基本的な情報、 たとえばクラスの名前、スーパークラスの情報、 クラス内部のメンバーの情報などを調べる機能を提供します。 また指定されたクラス名に対応する Classのオブジェクトや 指定されたクラスのオブジェクトを新しく生成するための手段も提供します。 (より正確に言うと Class はクラスだけではなく原始型、配列など Javaのすべての形式のデータに対応するオブジェクトを生成します。 int.classのような記述方法によって原始型のクラスのオブジェクトを 得ることができます。)

 クラスの内部のメンバーの情報を取り扱うためには、 それらを表すためのクラスも必要となるでしょう。 JDK1.1 から追加された java.lang.reflect パッケージには、 Field, Method, Constructor などのクラスが提供されています。 これらは、クラスの内部に定義されたフィールド、メソッド、コンストラクタの 情報を取り扱うためのクラスです。 これらのクラスと Classクラスによって、 アプリケーションがアプリケーション自身を構成するオブジェクトを記述することも 可能になるわけです。
 さらにクラスの外側の構造として、 パッケージというものが存在したことも思い出してください。 JDK1.2 からは java.lang パッケージに新たに追加された Packageクラスによって、 クラスが所属するパッケージについての情報も知ることができます。
 以上で述べた クラスの機能を試すためのサンプル MemberInfo.java を紹介しましょう。
このプログラムは実行時に引数としてクラス名を受け取ります。 そして指定されたクラスに関して、 スーパークラス名、パッケージ名、内部に定義されたフィールド、 コンストラクタ、メソッドの一覧を調べ標準出力に表示します。 次のように引数に適当なクラス名を与えて実行してみてください。 (JDKで提供されるクラスの名前でもかまいません。)


   java  MemberInfo  java.awt.Rectangle

Classクラス、Packageクラス、 および Field,Constructor, Methodクラスに用意された各メソッドによって、 クラスに関するさまざまな情報を得られることがわかるでしょう。 修飾子の情報は、やはり java.lang.reflect に所属する Modifierクラス を利用して知ることができます。 なお、Memberは Field,Constructor,Method に共通する性質を定義した インターフェイスです。 たとえば Methodクラスのみに関連する情報を取り出したい場合には、 (Method) のように明示的なキャストが必要になります。