リフレクション解説第二回~プログラムの内部構造をデータとして取得~|オブジェクト指向プログラミング(OOP)をおさらいしよう(8)
- TAG : Tech & Science | オブジェクト指向 | マーケティング・テクノロジスト
- POSTED : 2015.10.19 07:00
f t p h l
プログラムも「一個のデータ」です。
こんにちは。技術チームの岩谷です。本連載ではオブジェクト指向プログラミング(OOP)をおさらいする連載を書かせていただいています。前回「リフレクション」について説明させていただいたのですが、その中で
リフレクションとは「プログラムソースコードの記述規則にしたがってプログラムそのものを一個の”データ”とみなしてアクセスを行う技法」です。
と申し上げました。この部分をもう少し説明してほしいというご要望をいただいたので、今回執筆させてください。
今回、Javaソースを2本用意させていただきました。まず「データとして読み取られるクラス」です。(このクラスの具体的な処理内容については知っていただく必要はありません)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package jp.gixo.sample; public class Sample001 { public String str001; private String str002; public String getGoodMorning() { return "GoodMorning"; } private String getGoodNight() { return "GoodNight"; } } |
次に上記クラスの情報を読み取るクラスを掲載します。このクラスにはリフレクションのテクニックが含まれています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class SampleRun { public static void main(String[] args) { Class class1 = jp.gixo.sample.Sample001.class; System.out.println("\nクラスが持つフィールドの情報を出力します"); for(java.lang.reflect.Field field1:class1.getDeclaredFields()) { System.out.println(field1.toGenericString()); } System.out.println("\nクラスが持つメソッドの情報を出力します"); for(java.lang.reflect.Method method1:class1.getDeclaredMethods()) { System.out.println(method1.toGenericString()); } } } |
このプログラムを実行すると、以下のような出力結果が得られます。
1 2 3 4 5 6 7 |
クラスが持つフィールドの情報を出力します public java.lang.String jp.gixo.sample.Sample001.str001 private java.lang.String jp.gixo.sample.Sample001.str002 クラスが持つメソッドの情報を出力します public java.lang.String jp.gixo.sample.Sample001.getGoodMorning() private java.lang.String jp.gixo.sample.Sample001.getGoodNight() |
入力クラスである「Sample001」の情報が読み取られて画面上に出力されたのがお分かりいただけたと思います。具体的に説明をさせてください。まず、5行目で対象のクラスをClassオブジェクトに格納します。次に7行目で「このClassに格納されているフィールドの一覧」を取得しています。そして8行目から続くループ処理内でフィールドの情報を出力しています。ここでは、
- フィールドの名前
- フィールドの型
- フィールドのスコープ(private/publicなど)
を知ることができます。続く12行目からのコードは7行目からのそれとほとんど同じです。違いは7行目では「フィールドの一覧」を取得しているのに対して12行目では「メソッドの一覧」を取得している事です。
いかがでしょうか?5行目で与えられたクラスの情報からこれだけのことを知ることができました。これはまさにリフレクションの機能によって「プログラムがデータとして管理された状態」でそこからデータを取得する事が可能になっていると言えるのです。ちなみに先週の記事で「フレームワークとは?」という記事を執筆させていただきましたが、これらフレームワークにも今回紹介させていただいたテクニックが活かされています。
Note:
今回の記事ではサンプルソースを簡潔にするために「フィールドの一覧」「メソッドの一覧」を取得する方法を紹介させていただくにとどめましたが、これ以外にも「コンストラクタの一覧・アノテーションの一覧・インナークラスの一覧」など多くの「コンパイラが管理すべきデータ」を取得する事が可能です。
まるでEclipse?
ここまでの記事をお読みくださった皆さんは「あれ?これはまるでEclipseのコード補完機能そっくりじゃないか?」とお考えくださったと思います。まさにその通りです。Eclipseはその内部でリフレクションの機能を多用して多くの情報を開発者に提供してくれているのです。
【本連載について】
- OOPと非OOPの違い|オブジェクト指向プログラミング(OOP)をおさらいしよう(1)
- 継承によってコードを再利用する|オブジェクト指向プログラミング(OOP)をおさらいしよう(2)
- インターフェースとは?~継承とは役割が違う~|オブジェクト指向プログラミング(OOP)をおさらいしよう(3)
- カプセル化とは?~安全なシステムを作る為の配慮~|オブジェクト指向プログラミング(OOP)をおさらいしよう(4)
- 静的型付けと動的型付け~JavaとJavaScriptのJSON処理を比較~|オブジェクト指向プログラミング(OOP)をおさらいしよう(5)
- ポリモルフィズム(多態性)とは?~クラスは違えど同じ目的には同じメソッド名を~|オブジェクト指向プログラミング(OOP)をおさらいしよう(6)
- リフレクションとは?~文字列で指定されたクラスのメソッドを実行~|オブジェクト指向プログラミング(OOP)をおさらいしよう(7)
- リフレクション解説第二回~プログラムの内部構造をデータとして取得~|オブジェクト指向プログラミング(OOP)をおさらいしよう(8)
f t p h l