先日のClassクラスのnewInstance()は動的なインスタンス生成を実現したわけだけども、どうせなら動的に生成したインスタンスのメソッドを動的にinvokeしたい。
それを実現するのがjava.lang.reflect.Methodクラス。

ではここで、以下のようなa1メソッドを様々な引数でオーバーロードしたTestクラスを考える。

package a;
public class Test {
	public void a1(){
		System.out.println("I'm method a1()");
	}
	public void a1(int a){
		System.out.println("I'm method a1(int a))");
		System.out.println("a = " + a);
	}
	public void a1(int a, Object b){
		System.out.println("I'm method a1(int a, Object b");
		System.out.println("a = " + a);
		System.out.println("b.toString() = " + b);
	}
}

でこれらのメソッドを動的にinvokeするには・・・

package a;
public class Main {
    public static void main(String[] args){
        Class classInstance = Class.forName("a.Test");
		
//        Method m1 = classInstance.getMethod("a1", new Class[0]); //(1)
        Method m1 = classInstance.getMethod("a1"); //(2)
        m1.invoke(classInstance.newInstance(), new Object[0]); //(3)

        Class[] c1 = new Class[1];
        c1[0] = Integer.TYPE;
        Method m2 = classInstance.getMethod("a1", c1); //(4)
        m2.invoke(classInstance.newInstance(), new Integer(1)); //(5)
		
        Method m3 = classInstance.getMethod
                    ("a1", Integer.TYPE, new Object().getClass()); //(6)
        m3.invoke
        (classInstance.newInstance(), new Integer(2), new Object()); //(7)
    }
}

ここで、コメントアウトしてる(1) or (2)の部分はインスタンスから、引数がないメソッドa1を取得してる。引数が無いことを示すためには(1)のように空配列(empty array)指定することでも示せるし、(2)の部分のように何も書かないって事でも示すことができる。
また引数がある場合、クラスの種類を格納したClassクラスの配列を作り、それを(4)のようにgetMethodの第2引数にすることでメソッドを指定してもいいし、ただ型を示すClassクラスを並べるってだけでもいい。

このことは、メソッドをinvokeする場合も同じで((3),(5),(7))、引数を指定するのにObjectクラスの配列を利用してもいいし、そのまま(7)のように並べてもいい。

(注意)例外処理、importは簡単化のためソースから省いてるよ。

〜補足〜
ここで、Integerクラスのstaticフィールド、TYPEは、int のプリミティブ型を表すClassインスタンス
(7)では、int型の引数のところにラッパクラスであるIntegerを入れてるが、これは実際にinvokeする際、VMが自動的にアンラップしてくれる。