Java Reflectionクィックスタート

文:Peter V. Mikhalenko(special to TechRepublic)  翻訳校正:原井彰弘
2007-12-13 10:05:00
  • このエントリーをはてなブックマークに追加

 Javaにおいて、Reflectionとはプログラムの実行時にJavaのオブジェクトの内側を調べる技術を指す。Reflectionを用いることによって、オブジェクトに含まれている変数やオブジェクトがサポートしているメソッド、実装しているインタフェース、継承しているクラスなど、コンパイル時に決定しているオブジェクトの情報を基本的に全て手に入れることができる。

 Reflection APIはjava.lang.reflectパッケージに含まれており、どのような方法でJ2SEをインストールしても必ず含まれる。Reflection機能は、主にデータベースブラウザやビジュアルコードエディタのように、非常に汎用的なプログラムの開発を対象としたものであるが、ほかのアプリケーションの開発にも用いることが可能だ。Reflectionを用いると、前もって内容を知ることが困難なクラスファイルを扱えるようになるのである。ただし、Reflectionには非常に大きなオーバーヘッドが伴う。従って、Reflectionを用いる前には、その問題が一般的なインタフェースやClass.forName()メソッド、委譲オブジェクトでは解決できないということを確認すべきである。

 以下は、Reflectionを用いたコードの例である。

String methodName = "setName";
String someData = "TestName";
Class dynaclass = Class.forName( "TestClass" );

// メソッドは引数を受け取る。ここでは、Class[]としてメソッドの引数の型を順番に定義する
Class[] classParams = new Class [] { String. class};
// Classオブジェクトのメソッドをセットする
Method someMethod = dynaclass.getMethod( methodName, classParams );

// メソッドの引数として値を渡す
Object[] arguments = new Object [] { someData};
// reflectionsomeMethod.invoke( dynaclass.newInstance(), arguments );を用いてメソッドを呼び出す

 上記のコードは以下のコードと同じ意味である。

newTestClass().setName("TestName");

 この1つ目の例では、Reflectionを用いることによって新しく作成されたオブジェクトのメソッドを動的に呼び出した。この手法は非常に便利であるが、比較的遅い手法でもある。

基本的なテクニック

 Reflectionに関連した2つの基本的なテクニックが存在する。それは「発見」と「名前による使用」である。以下に双方の概要を述べる。

  • 「発見」はオブジェクトやクラスを受け取り、そのメンバやスーパークラス、実装しているインタフェースなどを見つけ出す。そして、普通はその後、見つけ出した要素を用いて何かを行う。
  • 「名前による使用」は、記号的な名前を付けられた要素に直接アクセスし、その要素を使用する。

 「発見」の典型的な流れは、まず対象となるオブジェクトが存在している状態から始まる。そして、Object.getClass()メソッドを呼び出すことによって、オブジェクトのClassを取得する。Classオブジェクトには、クラスの内容を調べるために多数のメソッドが用意されている。以下にそのメソッドの一部を紹介しよう。

  • getMethods() -- クラスまたはインタフェースの全てのpublicメソッドを、Methodオブジェクトの配列として返す。
  • getConstructors() -- クラスの全てのpublicコンストラクタを、Constructorオブジェクトの配列として返す。
  • getFields() -- クラスまたはインタフェースの全てのpublicフィールド変数を、Fieldオブジェクトの配列として返す。
  • getClasses() -- クラスまたはインタフェースに含まれている全てのpublicクラスまたはpublicインタフェース(内部クラスなど)を、Classオブジェクトの配列として返す。
  • getSuperclass() -- クラスまたはインタフェースのスーパークラスを、Classオブジェクトとして返す(インタフェースの場合はnullが返される)。
  • getInterfaces() -- クラスまたはインタフェースで実装されているインタフェースを、Classオブジェクトの配列として返す。
このサイトでは、利用状況の把握や広告配信などのために、Cookieなどを使用してアクセスデータを取得・利用しています。 これ以降ページを遷移した場合、Cookieなどの設定や使用に同意したことになります。
Cookieなどの設定や使用の詳細、オプトアウトについては詳細をご覧ください。
[ 閉じる ]