una reflexion reflect programacion por obtener metodo invocar example clase atributos java reflection invoke

reflexion - ¿Cómo invoco un método estático privado usando reflection(Java)?



reflexion java example (5)

Digamos que quieres llamar a 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

Me gustaría invocar un método estático privado. Tengo su nombre He oído que se puede hacer utilizando el mecanismo de reflexión de Java. ¿Cómo puedo hacerlo?

EDITAR: Un problema que encontré al intentar invocar el método es cómo especificar el tipo de su argumento. Mi método recibe un argumento y su tipo es Map. Por lo tanto, no puedo hacer Map<User, String>.TYPE (En tiempo de ejecución no existe Map por el borrado de Java Type). ¿Hay alguna otra forma de obtener el método?


Invocar principal del tutorial de reflexión

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


No, no puedes decir Map<K,V>.class . Esto se debe a borrado de tipo . En tiempo de ejecución, no hay tal cosa.

Afortunadamente, puedes decir simplemente viejo Map.class . Es todo lo mismo en tiempo de ejecución.

Si las advertencias te molestan, busca otras preguntas relacionadas con los genéricos y el tipo de borrado, aquí encontrarás una gran cantidad de información sobre el tema.


Utilizo un único método que encapsula obtener el método objetivo y luego invocarlo. Probablemente tiene algunas limitaciones, por supuesto. Aquí está el método puesto en una clase y su prueba 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

Hay una serie de excepciones marcadas que pueden arrojarse. Tanto los parameterTypes como los parámetros son argumentos de elipse (longitud variable), llénelos según sea necesario. La JVM por especificación tiene una convención de llamadas fuertemente tipada, por lo que debe conocer los tipos de parámetros.

Dicho esto, a menos que esté escribiendo algún tipo de contenedor de aplicaciones, contenedor de componentes de servidor, sistema tipo RMI o lenguaje basado en JVM, debe evitar hacerlo.