2009-11-23 7 views
16

Ich bin ziemlich neu in Java, und ich bin mit einem Reflexionsproblem konfrontiert.Mit Java Reflexion, wie ein neues Objekt zu instantiieren, dann rufen Sie eine Methode auf?

Sagen wir, ich muss dynamisch die Methode fooMethod auf eine Instanz der Klasse aufrufen Foobar

Ich habe bisher eine Instanz von Foobar mit:

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

Sagen wir, ich weiß, ein Verfahren gibt es fooMethod auf diesem Objekt (ich kann das auch mit Class.forName("Foobar").getDeclaredMethods() überprüfen), wie man es nennt, bitte?

Antwort

2

Dies sollte für Sie arbeiten:

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

Sie kann nur tun, wenn Sie bei der Kompilierung wissen, dass Instanz ein FooBar sein wird - das dann bedeutet, dass Sie Reflektion überhaupt nicht benötigen würden! – Chii

+2

@Chii: Nicht notwendig. FooBar könnte der allgemeinste Typ sein, von dem derjenige, den du durch Reflektion bekommst, erbt. So arbeiten zum Beispiel JDBC-Treiber und wie viele Plugin-Architekturen entworfen werden. – quosoo

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

Dies ist bei der Methode keine Argumente hat. Wenn dies der Fall ist, hängen Sie die Argumenttypen als Argumente an diese Methode an. obj ist das Objekt, für das Sie die Methode aufrufen.

See the java.lang.Class docs

+0

Was ist 'getClass'? –

3

Sie können here durch das Lesen darüber starten.

Wie für den Code, den Sie sind nach dem es so ist (aus der gleichen 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

Rein Reflexion: Method.invoke. Die andere Lösung besteht darin, das Element, das Sie reflektiv erstellen, zu benötigen, um eine bekannte Schnittstelle zu implementieren und diese Schnittstelle wie gewohnt zu verwenden.

Letzteres wird häufig für "Plugins" verwendet, das erstere wird nicht oft verwendet.

2

Sie verwenden können Reflection

Beispielklasse

package com.google.util; 
Class Maths 
{ 

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

und benutzen Sie folgende this-

Schritt 1: - Belastungsklasse mit gegebenen Eingangsnamen als String

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

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

Schritt 2: - get-Methode mit bestimmten Namen und Parametertyp

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

Schritt 3: - Methode Invoke Instanz vom Objekt und Argumente Indem

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

Sie tun können SCHRITT 2 WIE DIESES AUCH

(wenn Sie weiß nicht, bestimmte Methode existiert in einer Klasse, die Sie alle Methode überprüfen, indem Methode des Array Looping)

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

} 

} 
Verwandte Themen