2012-11-22 7 views
7

Sagen wir, ich habe Klassen A und B, wobei B erweitert A. Ich habe auch einen Konstruktor in B mit einem Argument, das vom Typ A ist. Ich habe auch ein Objekt vom Typ B namens bObj.Java Reflection getConstructor Methode

Gibt es eine Möglichkeit, B.class.getConstructor(new Class[] { bObj.getClass() }) aufrufen und den Konstruktor seit B erweitert A erhalten? Im Moment bekomme ich eine NoSuchMethodException.

Grüße, Stan

+2

Was ist 'B.class.getConstructors mit()' , finde die, die genau ein Argument nehmen, und überprüfe, ob 'A.class'' isAssignableFrom' dieses ist? –

+0

ist B Konstruktor Öffentlichkeit? –

+0

arne.b Dies ist eine Möglichkeit, aber ich dachte, es könnte tatsächlich einfacher sein. Nandkumar Ja, es ist öffentlich. –

Antwort

6

Ich schlage vor, dass Sie einen Blick auf die ConstructorUtils von Apache Commons Lang haben.
Sie haben alle Arten von Konstruktor-Erkennungsmethoden.

Ihr Fall sollte von "Matching Accessible Constructors" abgedeckt werden.

Here ist ein Beispiel der im Kontext verwendeten Methode. Grundsätzlich Sie es so nennen:

private <T> T instantiate(Class<?> input, Object parameter) { 
    try { 
    Constructor<?> constructor = ConstructorUtils.getMatchingAccessibleConstructor(input, parameter.getClass()); 
    return (T) constructor.newInstance(parameter); 
    } catch (Exception e) { 
    //handle various exceptions 
    } 
} 
+3

Das funktioniert einwandfrei und ist meiner Meinung nach ziemlich elegant. Zwei zusätzliche Hinweise: (1) Wenn Sie den Parameter "input" als "Class input" deklarieren, können Sie verhindern, dass der Rückgabewert umgewandelt wird. (2) 'ConstructorUtils.invokeConstructor (Klasse cls, Object ... args)' kombiniert das Abrufen des Konstruktors und das Erstellen einer neuen Instanz. –

3

Nein, die Methoden, die Suche nach Ihnen genauen Parameter erwarten. Wenn Sie also mithilfe von find/search-Methoden der Reflection-API nach einem Konstruktor, einer Methode oder einem Feld suchen, verwendet die API equals(), um Übereinstimmungen zu finden. Wenn Sie die gleiche Logik benötigen, die der Java-Compiler verwenden würde, müssen Sie ein Framework wie FEST Reflect oder commons beanutils verwenden. Oder Sie müssen getConstructors() anrufen und Ihren eigenen Filtercode schreiben.

Auf den ersten Blick scheint dies dumm: Wenn der Java-Compiler es tun kann, warum kann die Reflection API nicht? Dafür gibt es zwei Gründe: Erstens muss die Java-Laufzeitumgebung nicht nach der aufzurufenden Methode suchen, da der Compiler bereits die richtige Methode ausgewählt hat.

Der zweite Grund ist, dass die Reflection API immer "zweitbeste" war. Es kann alles tun, aber das Ziel war nie, es wirklich einfach/freundlich zu machen (zumindest denke ich jedes Mal wenn ich es benutze :-)

0

wenn Ihr Konstruktor nicht öffentlich ist (oder wenn es Klasse ist nicht öffentlich ist), oder nicht zugänglich aus dem Code Umfang, wird es nicht durch

Class.getConstructor() 
zurückgegeben werden

versuchen

Class.getDeclaredConstructor() 

statt