Method.invoke覚書
前回の日記でメソッドの動的実行の際にInteger→intに変更していました。
なんでIntegerができないのかと、悩んでいたのですが、解決したのでメモっときます。
invokeを実行するメソッドの引数の型の設定に問題あり
import java.lang.reflect.Method; class CalledClass{ public void func1(){ System.out.println("func1 no args"); } //引数Integer型 public void func2(Integer val){ System.out.println("func2: " + val); } } public class RefTest { @SuppressWarnings("unchecked") public static void main(String[] args) { try { Class[] c0 = new Class[0]; Class[] c1 = new Class[1]; //■ここがいけない //動的メソッドの引数の型 c1[0] = Integer.TYPE; //メソッド配列 Class<?> cls = Class.forName("CalledClass"); Method[] funcs = new Method[2]; //メソッドの参照設定 funcs[0] = cls.getMethod("func1", c0); funcs[1] = cls.getMethod("func2", c1); //呼び出し funcs[0].invoke(cls.newInstance(), c0); //■実行エラー funcs[1].invoke(cls.newInstance(), Integer.valueOf(5)); } catch (Exception e) { e.printStackTrace(); } } }
JavaDocより
Integer.TYPE
対象となるintのプリミティブ型を表すインスタンス
と記載されているのでNGだったと思われる
以下のように修正
c1[0] = Integer.TYPE; ↓ c1[0] = Integer.class;
修正ソース
import java.lang.reflect.Method; class CalledClass{ public void func1(){ System.out.println("func1 no args"); } public void func2(Integer val){ System.out.println("func2: " + val); } } public class RefTest { @SuppressWarnings("unchecked") public static void main(String[] args) { try { Class[] c0 = new Class[0]; Class[] c1 = new Class[1]; //■修正 c1[0] = Integer.class; Class<?> cls = Class.forName("CalledClass"); Method[] funcs = new Method[2]; funcs[0] = cls.getMethod("func1", c0); funcs[1] = cls.getMethod("func2", c1); funcs[0].invoke(cls.newInstance(), c0); //■今度はOK funcs[1].invoke(cls.newInstance(), Integer.valueOf(5)); } catch (Exception e) { e.printStackTrace(); } } }