Java リフレクション が簡単に
javaのリフレクションAPIを簡単に利用できるユーティリティークラスを紹介します。
リフレクションとは
リフレクションAPIは、「java.lang.reflect」パッケージに含まれており、
Javaクラスからフィールドやメソッドなどの情報を取得するAPIです。
主に以下のクラスを使用します。
- java.lang.Class
- java.lang.reflect.Constructor
- java.lang.reflect.Method
- java.lang.reflect.Field
リフレクションを使えば、クラス生成やメソッド呼び出しを直接コーディングすることなく、
文字列からクラスのインスタンスを生成したり、メソッドを実行することができます。
クラス名やメソッド名の定義はXMLなどの外部ファイルへ記述することで、アプリケーションを実行時の環境の変化に動的に対応させることができます。
また、柔軟性の高いアプリケーションを構築するうえで非常に有効なAPIとなっています。
リフレクションの目的
リフレクションはユーザーが直接使うことはあまり多くないのですが、
Struts等のWebアプリケーションやO/Rマッピング等のフレームワーク内では多用されています。
例えば、Web画面の入力データをJavaBeansプロパティに自動設定する場合や、
JavaBeansプロパティを元に自動的に更新するSQLを発行する場合などに利用されています。
また、アプリケーションの起動時に機能を拡張するプラグインを動的に読み込んで登録するといった機能はリフレクションを使うと簡単に実現できます。
サンプルの実行
では、サンプルを実行して頂き、是非フレームワーク的なプログラミングを体感してください。
ここでは以下のクラスを使用しリフレクションユーティリティの簡単な使い方を示しています。
Main.java・・・実行するクラス
BeanUtil.java・・・リフレクションのユーティリティクラス
FreeSoft.java・・・フリーソフを表すクラスでリフレクションとして利用されます。
●通常通り実行した場合
FreeSoft freeSoft = new FreeSoft();
freeSoft.setName(“Chat&Messenger チャットもメッセンジャーも!!”);
freeSoft.showName();
freeSoft.showPrice(0);
●リフレクションを使用して実行した場合
// FreeSoftクラスのインスタンス生成
Object invokeObject = BeanUtil.newInstance(“FreeSoft”);
// nameフィールドに値をセットする。
BeanUtil.setProperty(invokeObject, “name” , “Chat&Messenger チャットもメッセンジャーも!!”);
// FreeSoftのshowName()メソッドを実行します。
BeanUtil.invoke(invokeObject, “showName”, null);
// FreeSoftのshowPrice()メソッドを実行します。
// メソッドに引数がある場合はObject型の配列で渡す必要がある。
BeanUtil.invoke(invokeObject, “showPrice”,new Object[]{new Integer(0)});
●実行結果
通常の場合も、リフレクションを使用した場合も実行結果は同じですね。
ソフト名:Chat&Messenger チャットもメッセンジャーも!!
価格 :0円
>>>リフレクションを使用した場合
ソフト名:Chat&Messenger チャットもメッセンジャーも!!
価格 :0円
BeanUtilメソッド詳細
newInstance
public static Object newInstance(String className) throws Exception
- 文字列「className」からインスタンスを生成し返します。
-
- パラメータ:
className
– 完全修飾クラス名- 戻り値:
- 完全修飾クラス名の新しいインスタンス
- 例外:
Exception
newInstance
public static Object newInstance(String className, Object[] argObj) throws Exception
- 文字列「className」からインスタンスを生成し返します。
-
- パラメータ:
className
– 完全修飾クラス名argObj
– コンストラクタの引数- 戻り値:
- 完全修飾クラス名の新しいインスタンス
- 例外:
Exception
newInstance
public static Object newInstance(Class clazz) throws Exception
- クラス「clazz」からインスタンスを生成し返します。
-
- パラメータ:
clazz
– クラス- 戻り値:
- clazzの新しいインスタンス
- 例外:
Exception
newInstance
public static Object newInstance(Class clazz, Object[] argObj) throws Exception
- クラス「clazz」からインスタンスを生成し返します。
-
- パラメータ:
clazz
– クラスargObj
– コンストラクタの引数- 戻り値:
- clazzの新しいインスタンス
- 例外:
Exception
setProperty
public static void setProperty(Object invokeObject, String fieldName, Object value) throws Exception
- オブジェクト「invokeObject」のフィールド「fieldName」のsetterメソッドを 呼び出し、値「value」を格納します。
setterメソッドがなければフィールドへダイレクトに値を設定します。 ただし、この場合対象プロパティのアクセス修飾子はpublicであること
-
- パラメータ:
invokeObject
– 実行対象のオブジェクトfieldName
– 実行対象のオブジェクトのプロパティ名value
– セットする値- 例外:
Exception
– 以下の例外が発生します。InvocationTargetException
– 基本となるメソッドが例外をスローする場合IllegalAccessException
– この Method オブジェクトが Java
言語アクセス制御を実施し、基本となるメソッドにアクセスでき ない場合NoSuchMethodException
– 指定された名前のメソッドが見つからない場合
getProperty
public static Object getProperty(Object invokeObject, String fieldName) throws Exception
- オブジェクト invokeObject のフィールド fieldName のgetterメソッドを 呼び出し値を取得します。
getterメソッドがなければフィールドからダイレクトに値を取得します。 ただし、この場合対象プロパティのアクセス修飾子はpublicであること -
- パラメータ:
invokeObject
– 実行対象のオブジェクトfieldName
– 実行対象のオブジェクトのプロパティ名- 戻り値:
- ゲッターメソッドのリターン値
- 例外:
Exception
– 以下の例外が発生します。InvocationTargetException
– 基本となるメソッドが例外をスローする場合IllegalAccessException
– この Method オブジェクトが Java
言語アクセス制御を実施し、基本となるメソッドにアクセスでき ない場合NoSuchFieldException
– 指定された名前のフィールドが見つからない場合
invoke
public static Object invoke(Object invokeObject, String callMethod, Object[] argObjects) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException
- オブジェクト「invokeObject」のメソッド「callMethod」を実行します。
リターン値がある場合は、Object形として得る事ができます。 -
- パラメータ:
invokeObject
– 実行対象のオブジェクトcallMethod
– 実行対象のメソッド名argObjects
– 引数がある場合はオブジェクトの配列として渡す。 引数が無い場合はnullを渡します。- 戻り値:
- 「callMethod」を実行したリターン値
- 例外:
InvocationTargetException
– 基本となるメソッドが例外をスローする場合IllegalAccessException
– この Method オブジェクトが Java
言語アクセス制御を実施し、基本となるメソッドにアクセスでき ない場合NoSuchMethodException
– 指定された名前のメソッドが見つからない場合
findMethod
public static Method findMethod(Object invokeObject, String callMethod, Object[] argObjects) throws NoSuchMethodException
- オブジェクト「invokeObject」のメソッド「callMethod」を検索します。
-
- パラメータ:
invokeObject
– 実行対象のオブジェクトcallMethod
– 実行対象のオブジェクトのメソッド名argObjects
– 引数がある場合はオブジェクトの配列として渡す。 引数が無い場合はnullを渡します。- 戻り値:
- 指定された引数の条件に一致するMethod オブジェクト
- 例外:
NoSuchMethodException
– 一致するメソッドが見つからない場合、 あるいは名前が “” または “”の場合
setField
public static void setField(Object invokeObject, String fieldName, Object value) throws IllegalAccessException, NoSuchFieldException
- 実行対象のオブジェクト「invokeObject」のフィールド名「fieldName」に値 「value 」を格納します。
-
- パラメータ:
invokeObject
– 実行対象のオブジェクトfieldName
– 実行対象のオブジェクトのフィールド名value
– セットする値- 例外:
IllegalAccessException
– 指定されたオブジェクトが基本と なるフィールド (またはそのサブクラスか実装側)
を宣言する クラスまたはインタフェースのインスタンスではない場合、 ある いはラップ解除変換が失敗した場合NoSuchFieldException
– 指定された名前のフィールドが見つからない場合
getField
public static Object getField(Object invokeObject, String fieldName) throws IllegalAccessException, NoSuchFieldException
- 実行対象のオブジェクト「invokeObject」のフィールド名「fieldName」の値を 取得します。
-
- パラメータ:
invokeObject
– 実行対象のオブジェクトfieldName
– 実行対象のオブジェクトのフィールド名- 戻り値:
- リターン値
- 例外:
IllegalAccessException
– 指定されたオブジェクトが基本と なるフィールド (またはそのサブクラスか実装側)
を宣言する クラスまたはインタフェースのインスタンスではない場合、 ある いはラップ解除変換が失敗した場合NoSuchFieldException
– 指定された名前のフィールドが見つからない場合
hasField
public static boolean hasField(Object object, String fieldName) throws Exception
- オブジェクト「object」がフィールド名「fieldName」を 宣言しているかどうかを 確認します。
-
- パラメータ:
object
– 検査対象のオブジェクトfieldName
– 検査するフィールド名- 戻り値:
- 宣言している場合true
- 例外:
Exception
getAllFields
public static java.util.TreeSet getAllFields(Object object) throws Exception
-
- パラメータ:
object
–- 戻り値:
- 例外:
Exception
getShortClassName
public static String getShortClassName(Object object)
- オブジェクトから完全修飾していないクラス名を取得します。
-
- パラメータ:
object
–- 戻り値:
getShortClassName
public static String getShortClassName(String className)
- 完全修飾名からクラス名を取得します。
-
- パラメータ:
className
–- 戻り値:
getFieldName
public static String getFieldName(String methodName)
- メソッド名からフィールド名を変えします。 JavaBeansの慣例に適合している 必要があります。
-
- パラメータ:
methodName
–- 戻り値:
isClassExist
public static boolean isClassExist(String className)
- 完全修飾名「className」が存在するクラス名かを検証します。
-
- パラメータ:
className
–- 戻り値:
getPropertyDescriptors
public static PropertyDescriptor[] getPropertyDescriptors(Object object) throws IntrospectionException
- 「object」のオブジェクト情報を保持するPropertyDescriptorを返します。
-
- パラメータ:
object
–- 戻り値:
- 例外:
java.beans.IntrospectionException