2009-11-23 6 views
16

Je suis assez nouveau sur Java et je suis confronté à un problème de réflexion.Avec la réflexion Java comment instancier un nouvel objet, puis appeler une méthode dessus?

Disons que je dois appeler dynamiquement la méthode fooMethod sur une instance de la classe Foobar

je suis arrivé à ce jour une instance de Foobar avec:

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

Disons que je sais qu'il ya une méthode fooMethod sur cet objet (je peux même vérifier cela avec Class.forName("Foobar").getDeclaredMethods()), comment l'appeler, s'il vous plaît?

Répondre

2

Cela devrait fonctionner pour vous:

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

vous pouvez ne faire que si vous saviez au moment de la compilation, cette instance va être un FooBar - qui signifie alors que vous n'auriez pas besoin d'utiliser la réflexion en premier lieu! – Chii

+2

@Chii: Pas nécessairement. FooBar pourrait être le type le plus général dont hérite celui que vous obtenez à travers la réflexion. C'est ainsi que fonctionnent par exemple les pilotes JDBC et combien d'architectures de plugins sont conçues. – quosoo

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

C'est dans le cas où la méthode n'a pas d'arguments. Si c'est le cas, ajoutez les types d'arguments en tant qu'arguments à cette méthode. obj est l'objet sur lequel vous appelez la méthode.

See the java.lang.Class docs

+0

Qu'est-ce que 'getClass'? –

3

Vous pouvez commencer par lire à ce sujet here.

En ce qui concerne le code que vous êtes après est comme celui-ci (de la même ressource):

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

Purement réflexion: Method.invoke. L'autre solution consiste à exiger que l'élément que vous créez de manière réfléchie implémente une interface connue et soit casté sur cette interface et utilisé comme d'habitude. Ce dernier est couramment utilisé pour les "plugins", le premier n'est pas utilisé très souvent.

2

Vous pouvez utiliser l'échantillon Réflexion

classe

package com.google.util; 
Class Maths 
{ 

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

et utiliser quelque chose comme this-

étape 1: - Classe de charge avec le nom d'entrée donné comme chaîne

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

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

étape 2: - obtenir la méthode avec le nom donné et le type de paramètre

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

étape 3: - Invoquer Méthode par passage instance de l'objet et des arguments

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

vous pouvez faire ÉTAPE 2 COMME CELA AUSSI

(lorsque vous ne sais pas méthode particulière existe dans une classe que vous vérifiez toutes les méthodes en bouclant la gamme de méthode)

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]; 

} 

} 
Questions connexes