リフレクション
リフレクションをやってみます。リフレクションを使うとクラス名、メソッド名からメソッドを呼び出すことができます。クラス名、メソッド名を指定
リフレクションを使って、クラス名、メソッド名からメソッドを実行します。スタティックメソッドはそのまま呼び出せますが、通常のメソッドはオブジェクトを生成してからメソッドを呼び出します。Test.java
package javaTest;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
Test t = new Test();
// リフレクションでスタティックメソッドを実行
System.out.println(t.execStatic("javaTest.Test", "execStatic1"));
// リフレクションでスタティックメソッドを実行(引数あり)
System.out.println(t.execStatic("javaTest.Test", "execStatic2", "abc", "def"));
// リフレクションでメソッドを実行
System.out.println(t.exec("javaTest.Test", "exec1"));
// リフレクションでメソッドを実行(引数あり)
System.out.println(t.exec("javaTest.Test", "exec2", "aaa", "aaa"));
}
/**
* リフレクションでスタティックメソッドを実行
*
* @param className クラス名
* @param methodName メソッド名
* @return 戻り値
*/
public Object execStatic(String className, String methodName) {
Object ret = null;
try {
Class<?> clazz = Class.forName(className);
Method method = clazz.getMethod(methodName);
ret = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
/**
* リフレクションでスタティックメソッドを実行(引数あり)
*
* @param className クラス名
* @param methodName メソッド名
* @param arg1 引数1
* @param arg2 引数2
* @return 戻り値
*/
public Object execStatic(String className, String methodName, String arg1, String arg2) {
Object ret = null;
try {
Class<?> clazz = Class.forName(className);
Method method = clazz.getMethod(methodName, arg1.getClass(), arg2.getClass());
ret = method.invoke(null, arg1, arg2);
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
/**
* リフレクションでメソッドを実行
*
* @param className クラス名
* @param methodName メソッド名
* @return 戻り値
*/
public Object exec(String className, String methodName) {
Object ret = null;
try {
Class<?> clazz = Class.forName(className);
Method method = clazz.getMethod(methodName);
ret = method.invoke(getInstance(clazz));
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
/**
* リフレクションでメソッドを実行(引数あり)
*
* @param className クラス名
* @param methodName メソッド名
* @param arg1 引数1
* @param arg2 引数2
* @return 戻り値
*/
public Object exec(String className, String methodName, String arg1, String arg2) {
Object ret = null;
try {
Class<?> clazz = Class.forName(className);
Method method = clazz.getMethod(methodName, String.class, String.class);
ret = method.invoke(getInstance(clazz), arg1, arg2);
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
/**
* オブジェクトを生成
*
* @param clazz クラス
* @return オブジェクト
* @throws Exception 実行時例外
*/
public Object getInstance(Class<?> clazz) throws Exception {
Object ret = null;
Constructor<?> constructor = clazz.getConstructor();
ret = constructor.newInstance();
return ret;
}
public static void execStatic1() {
System.out.println("doStatic1");
}
public static String execStatic2(String arg1, String arg2) {
System.out.println("doStatic2");
return arg1 + arg2;
}
public void exec1() {
System.out.println("exec1");
}
public boolean exec2(String arg1, String arg2) {
System.out.println("exec2");
return arg1.equals(arg2);
}
}
実行結果
doStatic1
null
doStatic2
abcdef
exec1
null
exec2
true
クラス名のみ指定
クラス名からリフレクションを使って、オブジェクトを生成し、対象クラスにキャストして、メソッドを呼び出してみます。Test.java
package javaTest;
import java.lang.reflect.Constructor;
public class Test {
public static void main(String[] args) {
Test t = new Test();
// リフレクションでメソッドを実行
System.out.println(t.exec("javaTest.TestImpl", "aaa", "bbb"));
}
/**
* リフレクションでメソッドを実行(引数あり)
*
* @param className クラス名
* @param arg1 引数1
* @param arg2 引数2
* @return 戻り値
*/
public String exec(String className, String arg1, String arg2) {
try {
IfTest obj = (IfTest) getInstance(className);
return obj.execute(arg1, arg2);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* オブジェクトを生成
*
* @param className クラス名
* @return オブジェクト
* @throws Exception 実行時例外
*/
public Object getInstance(String className) throws Exception {
Object ret = null;
Class<?> clazz = Class.forName(className);
Constructor<?> constructor = clazz.getConstructor();
ret = constructor.newInstance();
return ret;
}
}
IfTest.java
package javaTest;
public interface IfTest {
public String execute(String arg1, String arg2);
}
TestImpl.java
package javaTest;
public class TestImpl implements IfTest {
@Override
public String execute(String arg1, String arg2) {
return arg1 + arg2;
}
}
実行結果
aaabbb
キャストしなくてもクラス指定でオブジェクト作成することもできます。
package javaTest;
import java.lang.reflect.Constructor;
public class Test {
public static void main(String[] args) {
Test t = new Test();
// リフレクションでメソッドを実行
System.out.println(t.exec("javaTest.TestImpl", "aaa", "bbb"));
}
/**
* リフレクションでメソッドを実行(引数あり)
*
* @param className クラス名
* @param arg1 引数1
* @param arg2 引数2
* @return 戻り値
*/
public String exec(String className, String arg1, String arg2) {
try {
IfTest obj = getInstance(className);
return obj.execute(arg1, arg2);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* オブジェクトを生成
*
* @param className クラス名
* @return オブジェクト
* @throws Exception 実行時例外
*/
public IfTest getInstance(String className) throws Exception {
IfTest ret = null;
Class<? extends IfTest> clazz = Class.forName(className).asSubclass(IfTest.class);
Constructor<? extends IfTest> constructor = clazz.getConstructor();
ret = constructor.newInstance();
return ret;
}
}
ページのトップへ戻る