久々にまじめなJavaネタです。リフレクションについて扱っていこうと思います。まずリフレクションとは、大雑把にいうとクラスのメンバの情報をインスタンスとして扱う事が出来る、そんな感じのAPIです。java.lang.reflectで始まるパッケージに属するクラスで処理を行う事ができます。例えばこんな感じのことができます。
- あるクラスから、ある名前とある引数の型に該当するメソッドを、オブジェクトとして取得して実行する
- あるクラスから、ある引数の型に該当するコンストラクタを、オブジェクトとして取得して、そのクラスのインスタンスを生成する
- あるクラスのある名前のフィールドの値を書き換える
- 等など・・・
のことができます。下はカンタンなサンプルです。
上記サンプルではmainメソッドのなかでFoo#bar()を直接実行していませんが、"bar"が出力されます。順を追って解説すると、
- 最初にFooクラスのコンストラクタを引数なしで取得
- そのコンストラクタのインスタンスのnewInstanceメソッドを呼び出してインスタンスを生成
- Fooクラスから引数なしで名前がbarというメソッドを取得
- そのメソッドオブジェクトのinvokeメソッドで対象のメソッドを実行
- barメソッドはインスタンスのメソッドなので、対象となる2で生成されたインスタンスを引数で渡す
と、この手順でインスタンスの生成、実行が行われます。
このAPIは使いどころに悩むAPIでもあるのですが、フレームワークを作るときには必須となるAPIです。また、プロパティが何十もあるようなJavaBeanからJavaBeanへの値の移し変えなどで活躍するAPIです。
今回はほんの入り口だけです。次はもうちょっと難しくなります。