2009-11-23 16 views
16

Soy bastante nuevo en Java, y estoy enfrentando un problema de reflexión.Con la reflexión de Java cómo instanciar un nuevo objeto, ¿luego invocar un método en él?

Digamos que tengo que llamar de forma dinámica el método fooMethod en una instancia de la clase Foobar

que tengo hasta ahora una instancia de Foobar con:

Object instance = Class.forName("Foobar").newInstance(); 

Digamos que sé que hay un método fooMethod en este objeto (incluso puedo verificar esto con Class.forName("Foobar").getDeclaredMethods()), cómo llamarlo, por favor?

Respuesta

2

Esto debería funcionar para usted:

((Foobar)instance).fooMethod() 
+1

sólo se puede hacer que si usted sabía en tiempo de compilación, esa instancia va a ser un FooBar - el cual ¡entonces significa que no necesitarías usar el reflejo en primer lugar! – Chii

+2

@Chii: No necesariamente. FooBar podría ser el tipo más general del que está heredando la que estás obteniendo a través del reflejo. Así es como funcionan los controladores JDBC y cuántas arquitecturas de plugins están diseñadas. – quosoo

6
Method method = getClass().getDeclaredMethod("methodName"); 
m.invoke(obj); 

Este es en caso de que el método no tiene argumentos. Si lo tiene, agregue los tipos de argumento como argumentos a este método. obj es el objeto al que está llamando el método.

See the java.lang.Class docs

+0

¿Qué es 'getClass'? –

3

Puedes empezar por leer sobre él here.

En cuanto al código que está después es así (desde el mismo recurso):

Method[] allMethods = c.getDeclaredMethods(); 
    for (Method m : allMethods) { 
    String mname = m.getName(); 
    if (!mname.startsWith("test") 
     || (m.getGenericReturnType() != boolean.class)) { 
     continue; 
    } 
    Type[] pType = m.getGenericParameterTypes(); 
    if ((pType.length != 1) 
     || Locale.class.isAssignableFrom(pType[0].getClass())) { 
     continue; 
    } 

    out.format("invoking %s()%n", mname); 
    try { 
     m.setAccessible(true); 
     Object o = m.invoke(t, new Locale(args[1], args[2], args[3])); 
     out.format("%s() returned %b%n", mname, (Boolean) o); 

    // Handle any exceptions thrown by method to be invoked. 
    } catch (InvocationTargetException x) { 
     Throwable cause = x.getCause(); 
     err.format("invocation of %s failed: %s%n", 
       mname, cause.getMessage()); 
    } 
4

puramente reflexión: Method.invoke. La otra solución es exigir que el elemento que está creando de forma reflexiva implemente una interfaz conocida y que se envíe a esta interfaz y que se use de la forma habitual.

Este último se utiliza comúnmente para "complementos", el primero no se usa con mucha frecuencia.

2

usted puede utilizar la reflexión

clase de muestra

package com.google.util; 
Class Maths 
{ 

public Integer doubleIt(Integer a) 
{ 
return a*2; 
} 
} 

y usar algo como esto:

paso 1: - Clase de carga con el nombre de entrada dado como cadena

Class<?> obj=Class.forName("Complete_ClassName_including_package"); 

//like:- Class obj=Class.forName("com.google.util.Maths"); 

Paso 2: - obtener Método con el nombre dado y el tipo de parámetro

Method method=obj.getMethod("NameOfMthodToInvoke", arguments); 

//arguments need to be like- java.lang.Integer.class 
//like:- Method method=obj.getMethod("doubleIt",java.lang.Integer.class); 

paso 3: - Invocar método por el que pasa Instancia de objeto y el argumento

Object obj2= method.invoke(obj.newInstance(), id); 
//like :- method.invoke(obj.newInstance(), 45); 

QUE PUEDE HACER PASO 2 COMO ESTO TAMBIÉN

(cuando no saben método particular existe en una clase de comprobar todo método por el bucle gama de método)

Method[] methods=obj.getMethods(); 

Method method=null; 

for(int i=0;i&lt;methods.length();i++) 

{ 

if(method[1].getName().equals("methodNameWeAreExpecting")) 

{ 

method=method[i]; 

} 

} 
Cuestiones relacionadas