リフレクションで関数を変数に入れて呼び出す。
呼び出したいクラス。適当に四則演算しているだけ。
Calc.java
package refrectiontest;
public class Calc {
public int plus(int a, int b) {
return a + b;
}
public int minus(int a, int b) {
return a - b;
}
public int multiply(int a, int b) {
return a * b;
}
public int divide(int a, int b) {
return a / b;
}
}
呼び出すところ。
RefrectionTest.java
package refrectiontest;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class RefrectionTest {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
try {
// インスタンスを作成する
Constructor<?> cons = Calc.class.getConstructor();
Calc calc = (Calc) cons.newInstance();
//使いたい関数名をリストへ登録
List<String> methodNames = new ArrayList<>();
methodNames.add("plus");
methodNames.add("minus");
methodNames.add("multiply");
methodNames.add("divide");
//登録した名前で関数をまとめて呼び出す。
//呼び出し元のシグネチャが違う場合は中で分岐するかfor文を分ける必要がある。
for(String methodName : methodNames){
//Method型の変数に関数ポインタを取得する。
//getMethod(上で作ったクラスインスタンス,使いたい関数の第一引数、第2引数、第3・・・)
//使いたいシグネチャの数だけmethod1,method2のように定義する。
Method method = (Calc.class.getMethod(methodName,int.class,int.class));
//関数の使用。invokeの戻り値はObject型なので対象の関数に合わせてキャストする。
int result = (int)method.invoke(calc,20,10);
System.out.println(methodName + " = " + result );
}
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException ex) {
Logger.getLogger(RefrectionTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
出力結果
plus = 30
minus = 10
multiply = 200
divide = 2
使い所
メソッドをString型で指定した時に便利かもしれない。
この例ではmethodNamesを一つづつ手打ちで足していますが、
呼び出したい関数名がmethod1,method2,method3,method4・・・
のように連番になっている場合は
for(int i = 1;i<10;i++){
"method" + String.valuOf(i) ;
}
のような感じで自動生成すればコードの短縮を測れるかもしれません。