2015-08-26 2 views
7

Ich habe eine Klasse in Jar, von dem ich eine Methode aufrufen möchte. Aber diese Methode hat Parameter der abstrakten Klasse und diese abstrakte Klasse ist die innere Methode der Klasse in jar. AbstractClassA ist eine HIDDEN-Klasse. Hier ist der Code:Abstract Callback in Reflektionsmethode von Java

public class A{ 

     private invokeThisMethod(AbstractClassA object){ 
     } 

     public abstract class AbstractClassA { 
       public void update(int remaining){} 
     } 
    } 



public class myClass{ 

    //using Reflection get object of class A 
     objectOfClassAusingReflection.inovke("invokeThisMethod", params) 
} 

Problem hier ist, wie kann ich die konkrete Umsetzung der AbstractClassA schaffen in invoke-Methode übergeben und Update-Methode Rückrufe bekommen?

+2

Wenn dies die API einer Bibliothek betrifft, müssen Sie möglicherweise in der Dokumentation der Bibliothek nach vorhandenen Unterklassen der inneren 'AbstractClassA' suchen.Normalerweise finden Sie entweder (1) eine spezifische Implementierung, die Sie über ihren Konstruktor instanziieren können, oder (2) eine Factory-Klasse, die Ihnen die Generierung einer solchen Instanz anbietet. Im schlimmsten Fall (3) müssen Sie es selbst implementieren, wie in der Antwort von KDM vorgeschlagen. – Carsten

Antwort

0

So etwas sollte funktionieren:

AbstractClassA a = new AbstractClassA() { 
     public void update(int remaining) {... do something...} 
}; 

objectOfClassAusingReflection.inovke("invokeThisMethod", a); 
+0

Nein. Das Erstellen eines Objekts der abstrakten Klasse ist nicht möglich. – user531069

+0

Dies ist eine anonyme Klasse von AbstractClassA. –

+0

@ user531069 Vorsicht die geschweiften Klammern hinter dem Konstruktor. Dies impliziert eine anonyme Unterklasse. 'new AbstractClassA() {/ * spezifische Implementierung * /}'. – Carsten

0

Sie können keine Instanz der abstrakten Klasse oder eine Schnittstelle zur Laufzeit erstellen. Erstellen Sie stattdessen eine anonyme Klasse.

public abstract class A { 
    public void fun(){....} 
    public abstract void absFun(); 
} 

public class MyClass { 
    objectOfClassA = new A(){ 
     public void absFun(){...} 
    } 
} 

Oder Sie können erste Implementierung für diese abstrakte Klassen erstellen, für die Sie eine andere Klasse erweitert A

class AWrapper extends A { 
    public class ImplementationClassA extends AbstractClassA { 
     // override abstract functions... 
    } 
} 

Jetzt können Sie diese Awrapper Klasse

AWrapper wrapperObj = new AWrapper(); 
A obj = wrapperObj; // just to make it clear that A can hold wrapperObj as it is implementation of it. 
A.AbstractClassA absObj = wrapperObj.new ImplementationClassA(); 
... 
objectOfClassAusingReflection.inovke("invokeThisMethod", params) 
0

Im Folgenden verwenden erstellen müssen Code sollte funktionieren--

Hier habe ichverwendetfür die äußere und innere Klasse und dann mit Hilfe von getdeclatedMethod genannt Ihre Update-Methode.

"TestAbs" ist Ihr Glas class--

public abstract class TestAbs { 

    private void invokeThisMethod(AbstractClassA object) { 
    } 

    public abstract class AbstractClassA { 
    public void update(int remaining) { 
    } 
    } 

} 

Dann wird Ihr Glas Klasse von "TestAbs1" wie below--

public class TestAbs1 { 

    public static void main(String[] args) { 
    TestAbs.AbstractClassA abs = new TestAbs() { 

     AbstractClassA a = new AbstractClassA() { 
     public void update(int remaining) { 
      System.out.println("Inside update method : " + remaining); 

     } 
     }; 
    }.a; 

    try { 
     int i = 1; 

     Class<?> class1 = Class.forName("app.test.mytest.TestAbs$AbstractClassA"); -- (*Getting instance of inner class*) 


     System.out.println(class1.getDeclaredMethod("update", int.class)); 
     class1.getDeclaredMethod("update", int.class).invoke(abs, i); 

    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    } 

} 

Der Ausgang bekam ich ruft -

public void app.test.mytest.TestAbs$AbstractClassA.update(int) 
Inside update method : 1 

Antwort auf Ihren Kommentar: -

Was ich aus Ihrem Kommentar verstand, ist, dass Sie die Methode von abstractClass aufrufen wollten, die in der äußeren Klasse versteckt ist.

Gemäß meinem Verständnis gibt es eine Möglichkeit, wie below--

public abstract class TestAbs { 

     private void invokeThisMethod(AbstractClassA object) { 
     } 

     private abstract class AbstractClassA { --- your hidden class 
     public void update(int remaining) { 
     } 
     } 

    public class ImplementedClass extends AbstractClassA{ -- use implemented class here 
     .... 
     ... 
    } 

    } 

Und danach, Ihre ImplementedClass die gleiche Art und Weise oben genannten verwenden. Sie können Referenzbeispiel für private innere Klasse here von Java-Dokumente finden.

Hinweis: In Ihrem Fragekontext, da Ihre innere Klasse und äußere Klasse in jar ist, denke ich, dass es schwierig ist, Implementierungsklasse in Ihr jar hinzuzufügen.

Falls Sie irgendwelche Alternativen finden, lassen Sie es bitte alle wissen;

danke.

+0

Das sieht wirklich gut aber löst mein Problem nicht vollständig. Gibt es eine Möglichkeit, anstatt die Update-Methode aufzurufen, höre ich es, wenn eine andere Klasse es aufruft? Wie ich Callbacks bekomme, wann immer Update ausgelöst wird. – user531069

+0

Was ist AbstractClassA ist eine versteckte Klasse, was bedeutet, dass ich nicht direkt darauf zugreifen kann, wie Sie es getan haben. Wie benutze ich es mit Reflektion? – user531069