2012-11-22 20 views
7

Diciamo che ho classi A e B, dove B si estende A. Ho anche un costruttore in B con un argomento che è di tipo A. Ho anche un oggetto di tipo B chiamato bObj.metodo Java Reflection getConstructor

C'è un modo per chiamare B.class.getConstructor(new Class[] { bObj.getClass() }) e ottenere il costruttore dal B estende A? Al momento sto ricevendo un NoSuchMethodException.

saluti, Stan

+2

Cosa succede ad usare 'B.class.getConstructors()' , trova quelli che prendono esattamente un argomento e controlla se 'A.class'' èAssignableFrom' questo? –

+0

è il pubblico di costruttore di B? –

+0

arne.b Questo è un modo per farlo ma ho pensato che potesse essere effettivamente più semplice. Nandkumar Sì, è pubblico. –

risposta

6

Ti suggerisco di dare un'occhiata allo Apache Commons LangConstructorUtils.
Hanno tutti i metodi di metodi di ricerca del costruttore.

Il tuo caso dovrebbe essere coperto da "Matching Accessible Constructors".

Here è un esempio del metodo utilizzato nel contesto. In sostanza, si chiama così:

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

Funziona perfettamente ed è, a mio parere, abbastanza elegante. Due ulteriori suggerimenti: (1) Se si dichiara il parametro "input" come "Classe input", è possibile evitare di trasmettere il valore restituito. (2) 'ConstructorUtils.invokeConstructor (Classe cls, Object ... args)' combina ottenendo il costruttore e creando una nuova istanza. –

3

No, i metodi che ricerca ci si aspetta parametri esatti. Pertanto, quando si cerca un costruttore, un metodo o un campo utilizzando i metodi di ricerca/ricerca dell'API di riflessione, l'API utilizza equals() per trovare le corrispondenze.

Se è necessaria la stessa logica utilizzata dal compilatore Java, sarà necessario utilizzare un framework come FEST Reflect o commons beanutils. O è necessario chiamare getConstructors() e scrivere il proprio codice di filtro.

A prima vista, questo sembra stupido: se il compilatore Java può farlo, perché non può l'API di Reflection? Ci sono due ragioni: in primo luogo, il runtime Java non ha bisogno di cercare quale metodo chiamare perché il compilatore ha già selezionato il metodo corretto.

Il secondo motivo è che l'API di Reflection è sempre stata "la seconda migliore". Può fare tutto ma l'obiettivo non è mai stato renderlo veramente facile/amichevole da usare (almeno, questo è quello che penso ogni volta che lo uso :-)

0

se il costruttore non è pubblico (o se si tratta di classe non è pubblico), o non accessibile dal proprio campo di applicazione del codice, non sarà restituita attraverso

Class.getConstructor() 

provare

Class.getDeclaredConstructor() 

invece

Problemi correlati