sirve que para misma metodo llamar invoca como clase java reflection invoke

que - metodo void java



¿Cómo invoco un método Java cuando se le da el nombre del método como una cadena? (18)

Si tengo dos variables:

Object obj; String methodName = "getName";

Sin saber la clase de obj , ¿cómo puedo llamar al método identificado por methodName en él?

El método al que se llama no tiene parámetros y un valor de retorno de String . Es un getter para un bean Java .


Estudiante.java

class Student{ int rollno; String name; void m1(int x,int y){ System.out.println("add is" +(x+y)); } private void m3(String name){ this.name=name; System.out.println("danger yappa:"+name); } void m4(){ System.out.println("This is m4"); } }

StudentTest.java

import java.lang.reflect.Method; public class StudentTest{ public static void main(String[] args){ try{ Class cls=Student.class; Student s=(Student)cls.newInstance(); String x="kichha"; Method mm3=cls.getDeclaredMethod("m3",String.class); mm3.setAccessible(true); mm3.invoke(s,x); Method mm1=cls.getDeclaredMethod("m1",int.class,int.class); mm1.invoke(s,10,20); } catch(Exception e){ e.printStackTrace(); } } }


Codificación desde la cadera, sería algo así como:

java.lang.reflect.Method method; try { method = obj.getClass().getMethod(methodName, param1.class, param2.class, ..); } catch (SecurityException e) { ... } catch (NoSuchMethodException e) { ... }

Los parámetros identifican el método muy específico que necesita (si hay varios sobrecargados disponibles, si el método no tiene argumentos, solo proporcione methodName ).

Entonces invocas ese método llamando

try { method.invoke(obj, arg1, arg2,...); } catch (IllegalArgumentException e) { ... } catch (IllegalAccessException e) { ... } catch (InvocationTargetException e) { ... }

Nuevamente, .invoke los argumentos en .invoke , si no tiene ninguno. Pero sí. Leer sobre Java Reflection


Debe usar la reflexión: inicie un objeto de clase, luego un método en esta clase y luego invoque este método en un objeto con parámetros opcionales . Recuerda envolver el siguiente fragmento en el bloque try-catch

¡Espero eso ayude!

Class<?> aClass = Class.forName(FULLY_QUALIFIED_CLASS_NAME); Method method = aClass.getMethod(methodName, YOUR_PARAM_1.class, YOUR_PARAM_2.class); method.invoke(OBJECT_TO_RUN_METHOD_ON, YOUR_PARAM_1, YOUR_PARAM_2);


El método puede ser invocado así. También hay más posibilidades (verifique la api de reflexión), pero esta es la más simple:

import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.junit.Assert; import org.junit.Test; public class ReflectionTest { private String methodName = "length"; private String valueObject = "Some object"; @Test public void testGetMethod() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException { Method m = valueObject.getClass().getMethod(methodName, new Class[] {}); Object ret = m.invoke(valueObject, new Object[] {}); Assert.assertEquals(11, ret); } }


Esto está funcionando bien para mí:

public class MethodInvokerClass { public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, ClassNotFoundException, InvocationTargetException, InstantiationException { Class c = Class.forName(MethodInvokerClass.class.getName()); Object o = c.newInstance(); Class[] paramTypes = new Class[1]; paramTypes[0]=String.class; String methodName = "countWord"; Method m = c.getDeclaredMethod(methodName, paramTypes); m.invoke(o, "testparam"); } public void countWord(String input){ System.out.println("My input "+input); }

}

Salida:

My input testparam

Puedo invocar el método pasando su nombre a otro método (como main).


Esto suena como algo que se puede hacer con el paquete Java Reflection.

http://java.sun.com/developer/technicalArticles/ALT/Reflection/index.html

Particularmente bajo los métodos de invocación por nombre:

importar java.lang.reflect. *;

public class method2 { public int add(int a, int b) { return a + b; } public static void main(String args[]) { try { Class cls = Class.forName("method2"); Class partypes[] = new Class[2]; partypes[0] = Integer.TYPE; partypes[1] = Integer.TYPE; Method meth = cls.getMethod( "add", partypes); method2 methobj = new method2(); Object arglist[] = new Object[2]; arglist[0] = new Integer(37); arglist[1] = new Integer(47); Object retobj = meth.invoke(methobj, arglist); Integer retval = (Integer)retobj; System.out.println(retval.intValue()); } catch (Throwable e) { System.err.println(e); } } }


Hago esto así:

try { YourClass yourClass = new YourClass(); Method method = YourClass.class.getMethod("yourMethodName", ParameterOfThisMethod.class); method.invoke(yourClass, parameter); } catch (Exception e) { e.printStackTrace(); }


Para aquellos que quieren un ejemplo de código directo en Java 7:

Clase de Dog

package com.mypackage.bean; public class Dog { private String name; private int age; public Dog() { // empty constructor } public Dog(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void printDog(String name, int age) { System.out.println(name + " is " + age + " year(s) old."); } }

Clase ReflectionDemo :

package com.mypackage.demo; import java.lang.reflect.*; public class ReflectionDemo { public static void main(String[] args) throws Exception { String dogClassName = "com.mypackage.bean.Dog"; Class<?> dogClass = Class.forName(dogClassName); // convert string classname to class Object dog = dogClass.newInstance(); // invoke empty constructor String methodName = ""; // with single parameter, return void methodName = "setName"; Method setNameMethod = dog.getClass().getMethod(methodName, String.class); setNameMethod.invoke(dog, "Mishka"); // pass arg // without parameters, return string methodName = "getName"; Method getNameMethod = dog.getClass().getMethod(methodName); String name = (String) getNameMethod.invoke(dog); // explicit cast // with multiple parameters methodName = "printDog"; Class<?>[] paramTypes = {String.class, int.class}; Method printDogMethod = dog.getClass().getMethod(methodName, paramTypes); printDogMethod.invoke(dog, name, 3); // pass args } }

Salida: Mishka is 3 year(s) old.

Puedes invocar el constructor con parámetros de esta manera:

Constructor<?> dogConstructor = dogClass.getConstructor(String.class, int.class); Object dog = dogConstructor.newInstance("Hachiko", 10);

Alternativamente, puede eliminar

String dogClassName = "com.mypackage.bean.Dog"; Class<?> dogClass = Class.forName(dogClassName); Object dog = dogClass.newInstance();

y hacer

Dog dog = new Dog(); Method method = Dog.class.getMethod(methodName, ...); method.invoke(dog, ...);

Lectura sugerida: Creación de nuevas instancias de clase


Para completar las respuestas de mi colega, es posible que desee prestar mucha atención a:

  • llamadas estáticas o de instancia (en un caso, no necesita una instancia de la clase; en el otro, es posible que deba confiar en un constructor predeterminado existente que puede o no estar allí)
  • Llamada de método público o no público (para este último, debe llamar a setAccessible en el método dentro de un bloque doPrivileged , otros errores de búsqueda no estarán contentos )
  • encapsular en una excepción aplicativa más manejable si desea rechazar las numerosas excepciones del sistema Java (de ahí la excepción CCE en el código a continuación)

Aquí hay un antiguo código java1.4 que tiene en cuenta esos puntos:

/** * Allow for instance call, avoiding certain class circular dependencies. <br /> * Calls even private method if java Security allows it. * @param aninstance instance on which method is invoked (if null, static call) * @param classname name of the class containing the method * (can be null - ignored, actually - if instance if provided, must be provided if static call) * @param amethodname name of the method to invoke * @param parameterTypes array of Classes * @param parameters array of Object * @return resulting Object * @throws CCException if any problem */ public static Object reflectionCall(final Object aninstance, final String classname, final String amethodname, final Class[] parameterTypes, final Object[] parameters) throws CCException { Object res;// = null; try { Class aclass;// = null; if(aninstance == null) { aclass = Class.forName(classname); } else { aclass = aninstance.getClass(); } //Class[] parameterTypes = new Class[]{String[].class}; final Method amethod = aclass.getDeclaredMethod(amethodname, parameterTypes); AccessController.doPrivileged(new PrivilegedAction() { public Object run() { amethod.setAccessible(true); return null; // nothing to return } }); res = amethod.invoke(aninstance, parameters); } catch (final ClassNotFoundException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+CLASS, e); } catch (final SecurityException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+GenericConstants.HASH_DIESE+ amethodname + METHOD_SECURITY_ISSUE, e); } catch (final NoSuchMethodException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+GenericConstants.HASH_DIESE+ amethodname + METHOD_NOT_FOUND, e); } catch (final IllegalArgumentException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+GenericConstants.HASH_DIESE+ amethodname + METHOD_ILLEGAL_ARGUMENTS+String.valueOf(parameters)+GenericConstants.CLOSING_ROUND_BRACKET, e); } catch (final IllegalAccessException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+GenericConstants.HASH_DIESE+ amethodname + METHOD_ACCESS_RESTRICTION, e); } catch (final InvocationTargetException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+GenericConstants.HASH_DIESE+ amethodname + METHOD_INVOCATION_ISSUE, e); } return res; }


Para mí, una forma bastante simple y a prueba de tontos sería simplemente hacer un método de llamador de método como tal:

public static object methodCaller(String methodName) { if(methodName.equals("getName")) return className.getName(); }

Luego, cuando necesite llamar al método, simplemente coloque algo como esto.

//calling a toString method is unnessary here, but i use it to have my programs to both rigid and self-explanitory System.out.println(methodCaller(methodName).toString());


Por favor, consulte el siguiente código puede ayudarle.

public static Method method[]; public static MethodClass obj; public static String testMethod="A"; public static void main(String args[]) { obj=new MethodClass(); method=obj.getClass().getMethods(); try { for(int i=0;i<method.length;i++) { String name=method[i].getName(); if(name==testMethod) { method[i].invoke(name,"Test Parameters of A"); } } } catch(Exception ex) { System.out.println(ex.getMessage()); } }

Gracias....



Si hace la llamada varias veces, puede usar los nuevos manejadores de métodos introducidos en Java 7. Aquí vamos para su método que devuelve una cadena:

Object obj = new Point( 100, 200 ); String methodName = "toString"; Class<String> resultType = String.class; MethodType mt = MethodType.methodType( resultType ); MethodHandle methodHandle = MethodHandles.lookup().findVirtual( obj.getClass(), methodName, mt ); String result = resultType.cast( methodHandle.invoke( obj ) ); System.out.println( result ); // java.awt.Point[x=100,y=200]


Usar invocación de método desde la reflexión:

Class<?> c = Class.forName("class name"); Method method = c.getDeclaredMethod("method name", parameterTypes); method.invoke(objectToInvokeOn, params);

Dónde:

  • "class name" es el nombre de la clase
  • objectToInvokeOn es de tipo Object y es el objeto en el que desea invocar el método
  • "method name" es el nombre del método que desea llamar
  • parameterTypes es de tipo Class[] y declara los parámetros que toma el método
  • params es de tipo Object[] y declara los parámetros que se deben pasar al método

utilizando import java.lang.reflect.*;

public static Object launchProcess(String className, String methodName, Class<?>[] argsTypes, Object[] methodArgs) throws Exception { Class<?> processClass = Class.forName(className); // convert string classname to class Object process = processClass.newInstance(); // invoke empty constructor Method aMethod = process.getClass().getMethod(methodName,argsTypes); Object res = aMethod.invoke(process, methodArgs); // pass arg return(res); }

Y aquí es cómo lo usas:

String className = "com.example.helloworld"; String methodName = "print"; Class<?>[] argsTypes = {String.class, String.class}; Object[] methArgs = { "hello", "world" }; launchProcess(className, methodName, argsTypes, methArgs);


//Step1 - Using string funClass to convert to class String funClass = "package.myclass"; Class c = Class.forName(funClass); //Step2 - instantiate an object of the class abov Object o = c.newInstance(); //Prepare array of the arguments that your function accepts, lets say only one string here Class[] paramTypes = new Class[1]; paramTypes[0]=String.class; String methodName = "mymethod"; //Instantiate an object of type method that returns you method name Method m = c.getDeclaredMethod(methodName, paramTypes); //invoke method with actual params m.invoke(o, "testparam");


Method method = someVariable.class.getMethod(SomeClass); String status = (String) method.invoke(method);

SomeClass es la clase y someVariable es una variable.


Object obj; Method method = obj.getClass().getMethod("methodName", null); method.invoke(obj, null);