String 형태의 함수이름을 가지고 함수를 호출하는 방법을 설명한다.
이에 사용한 방법은 reflect의 method이다.
먼저 임의의 class에 함수A와 함수B를 선언한다.
함수A는 parameter가 없는 형태의 함수이며, 함수B는 parameter가 있으며 return 값이 있는 경우이다.
두가지의 함수를 통해 함수이름을 통한 호출을 해본다.
static class subTest {
public void funcA()
{
///
}
public boolean funcB(boolean param1, int param2)
{
///
}
}
함수A type 호출
Class는 기본적으로 제공되므로 따로 import할 필요는 없으며, forName에는 호출하게 될 class의 name을 전달한다.
이 때 필요한 exception 처리는 ClassNotFoundException가 해당된다. 일치하는 Class가 없을 경우에 예외처리 된다.
아래에서 class 전달 시 Object 형태로 전달하였으나 class를 생성하여 바로 전달할 수 있다. 최종 invoke시에도 사용하기 위해 편의상 Object 형태로 선언하였다.
이를 통해 Class의 getDeclaredMethod를 이용하여 Method를 얻어올 수 있다. 이 때 subTest Class의 함수A의 이름인 funcA를 parameter로 전달하여 얻어온다. 이때 필요한 exception 처리는 NoSuchMethodException이 된다. 해당하는 함수이름이 없어 Method를 가져오지 못하는 경우 예외처리가 되는 것이다.
최종 Method의 invoke를 이용하여 함수를 호출 할 수 있으며, 해당 Class(Object)를 전달한다. 이 때 필요한 exception 처리는 InvocationTargetException과 IllegalAccessException이며, import가 필요한 부분이다.
package hello;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class test {
static class subTest {
public void funcA()
{
System.out.println("funcA(): " + this.getClass().getName());
}
public boolean funcB(boolean param1, int param2)
{
boolean ret = param1;
System.out.println("funcB(): " + this.getClass().getName());
System.out.println("param1: " + param1);
System.out.println("param2: " + param2);
return ret;
}
}
public static void main(String[] args)
{
String functionNameA = "funcA";
Object obj = new subTest();
try {
Class<?> cls = Class.forName(obj.getClass().getName());
Method m = cls.getDeclaredMethod(functionNameA);
m.invoke(obj);
}
catch (ClassNotFoundException e) {
System.out.println("ClassNotFoundException from Class.forName()");
}
catch (NoSuchMethodException e) {
System.out.println("NoSuchMethodException from getDeclaredMethod()");
}
catch (InvocationTargetException e) {
System.out.println("InvocationTargetExceptionn from invoke()");
}
catch (IllegalAccessException e) {
System.out.println("IllegalAccessException from invoke()");
}
finally {
System.out.println("functionA test success!");
}
}
}
실행 결과는 아래와 같다.
함수B type 호출
함수의 parameter가 있으며 return type이 정의된 경우이다. 기본 내용은 위와 동일하며 getDeclaredMethod를 사용할 경우 parameter.class type을 추가해준다. 함수B의 parameter type과 동일하게 선언해 주어야 하며 return 값도 전달 받을 수 있다. return 값의 경우 해당 data type으로 casting이 필요하다. 아래와 같이 return type이 bool인 경우 invoke 함수 호출 결과를 bool type으로 casting하여 전달 받을 수 있다.
package hello;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class test {
static class subTest {
public void funcA()
{
///
}
public boolean funcB(boolean param1, int param2)
{
///
}
}
public static void main(String[] args)
{
String functionNameB = "funcB";
boolean result = false;
try {
Class<?> cls = Class.forName(obj.getClass().getName());
Method m = cls.getDeclaredMethod(functionNameB, boolean.class, int.class);
result = (boolean) m.invoke(obj, true, 10);
System.out.println("result: " + result);
}
catch (ClassNotFoundException e) {
System.out.println("ClassNotFoundException from Class.forName()");
}
catch (NoSuchMethodException e) {
System.out.println("NoSuchMethodException from getDeclaredMethod()");
}
catch (InvocationTargetException e) {
System.out.println("InvocationTargetExceptionn from invoke()");
}
catch (IllegalAccessException e) {
System.out.println("IllegalAccessException from invoke()");
}
finally {
System.out.println("functionB test success!");
}
}
}
실행 결과는 아래와 같다.
'java' 카테고리의 다른 글
[java] No enclosing instance of type xxx is accessible 에러 (0) | 2021.08.09 |
---|---|
[java] ConcurrentHashMap iterator 사용법 (0) | 2020.12.16 |
댓글