How do I invoke a private static method using reflection (Java)?

前端 未结 5 397
[愿得一人]
[愿得一人] 2020-11-29 03:32

I would like to invoke a private static method. I have its name. I\'ve heard it can be done using Java reflection mechanism. How can I do it?

EDIT:

相关标签:
5条回答
  • 2020-11-29 03:40

    Let's say you want to call 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
    
    0 讨论(0)
  • 2020-11-29 03:55
    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
    

    There are a number of checked exceptions which may be thrown. Both parameterTypes and parameters are ellipse arguments (variable length), fill them in as needed. The JVM by specification has a strongly typed calling convention so you need to know the parameter types.

    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.

    0 讨论(0)
  • 2020-11-29 03:56

    I use a single method that encapsulates getting the target method and then invoking it. Probably has some limitations, of course. Here is the method put into a class and its JUnit test:

    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));
    
        }
    }
    

    }

    0 讨论(0)
  • 2020-11-29 04:00

    No, you can't say Map<K,V>.class. This is because of type erasure. At runtime, there's no such thing.

    Luckily, you can say just plain old Map.class. It's all the same at runtime.

    If the warnings bother you, search for other questions related to generics and type erasure, there's a wealth of information on the subject here.

    0 讨论(0)
  • 2020-11-29 04:04

    Invoke main from reflection tutorial

    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();
        }
        }
    }
    
    0 讨论(0)
提交回复
热议问题