IT TIP

리플렉션 (Java)을 사용하여 개인 정적 메서드를 어떻게 호출합니까?

itqueen 2020. 12. 15. 20:38
반응형

리플렉션 (Java)을 사용하여 개인 정적 메서드를 어떻게 호출합니까?


개인 정적 메서드를 호출하고 싶습니다. 이름이 있습니다. Java 리플렉션 메커니즘을 사용하여 수행 할 수 있다고 들었습니다. 내가 어떻게 해?

편집 : 메서드를 호출 할 때 발생한 한 가지 문제는 인수 유형을 지정하는 방법입니다. 내 메서드는 하나의 인수를 받고 해당 유형은 Map입니다. 따라서 할 수 없습니다 Map<User, String>.TYPE(런타임에는 Java 유형 삭제로 인해 Map과 같은 것이 없습니다). 방법을 얻는 다른 방법이 있습니까?


MyClass.myMethod (int x);를 호출한다고 가정 해 보겠습니다.

Method m = MyClass.class.getDeclaredMethod("myMethod", Integer.TYPE);
m.setAccessible(true); //if security settings allow this
Object o = m.invoke(null, 23); //use null if the method is static

리플렉션 튜토리얼 에서 메인 호출

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

public class InvokeMain {
    public static void main(String... args) {
    try {
        Class<?> c = Class.forName(args[0]);
        Class[] argTypes = new Class[] { String[].class };
        Method main = c.getDeclaredMethod("main", argTypes);
        String[] mainArgs = Arrays.copyOfRange(args, 1, args.length);
        System.out.format("invoking %s.main()%n", c.getName());
        main.invoke(null, (Object)mainArgs);

        // production code should handle these exceptions more gracefully
    } catch (ClassNotFoundException x) {
        x.printStackTrace();
    } catch (NoSuchMethodException x) {
        x.printStackTrace();
    } catch (IllegalAccessException x) {
        x.printStackTrace();
    } catch (InvocationTargetException x) {
        x.printStackTrace();
    }
    }
}

아니, 말할 수 없습니다 Map<K,V>.class. 이것은 유형 삭제 때문입니다 . 런타임에는 그런 것이 없습니다.

다행히도 그냥 평범한 낡은이라고 말할 있습니다Map.class . 런타임에 모두 동일합니다.

경고가 귀찮다면 제네릭 및 유형 삭제와 관련된 다른 질문을 검색하십시오. 여기에 주제에 대한 풍부한 정보가 있습니다.


대상 메서드를 가져 와서 호출하는 단일 메서드를 사용합니다. 물론 몇 가지 제한 사항이있을 것입니다. 다음은 클래스에 넣은 메소드와 JUnit 테스트입니다.

public class Invoker {
/**
 * Get method and invoke it.
 * 
 * @author jbetancourt
 * 
 * @param name of method
 * @param obj Object to invoke the method on
 * @param types parameter types of method
 * @param args to method invocation
 * @return return value
 * @throws Exception for unforseen stuff
 */
public static final <T> Object invokeMethod(final String name, final T obj,
  final Class<?>[] types, final Object... args) throws Exception {

    Method method = obj.getClass().getDeclaredMethod(name, types);
    method.setAccessible(true);
    return method.invoke(obj, args);
}

/**
 * Embedded JUnit tests.
 */
@RunWith(JUnit4.class)
public static class InvokerTest {
    /** */
    @Test
    public void testInvoke() throws Exception {
        class TestTarget {
            private String hello() {
                return "Hello world!";
            }
        }

        String actual = (String) Invoker.invokeMethod("hello",
                new TestTarget(), new Class<?>[] {});
        String expected = "Hello world!";
        assertThat(actual, is(expected));

    }
}

}


Object insecure; //This needs to be an initialized reference

Class c = insecure.getClass();
Method m = c.getMethod(name, parameterTypes); //Fill the name and types in
m.setAccessible(true);
m.invoke( insecure, parameters ); //Fill in the parameters you would like

throw 될 수있는 확인 된 예외가 많이 있습니다. parameterTypes 및 매개 변수는 모두 타원 인수 (가변 길이)이며 필요에 따라 채우십시오. 사양 별 JVM에는 강력한 유형의 호출 규칙이 있으므로 매개 변수 유형을 알아야합니다.

With that said, unless you are writing some sort of application container, server component container, RMI-like system, or JVM based langauge you should avoid doing this.

ReferenceURL : https://stackoverflow.com/questions/4770425/how-do-i-invoke-a-private-static-method-using-reflection-java

반응형