La
riflessione Java è uno strumento potente, per scrivere programmi che possono elaborare dinamicamente il codice Java. Un programma è riflessivo se è in grado di analizzare le funzionalità delle classi. La riflessione Java è uno strumento utilizzato sopratutto da coloro che realizzano strumenti per lo sviluppo. Iniziamo la nostra navigazione all'interno delle classi che la libreria standard Java ci mette a disposizione per utilizzare questo potente strumento.
Le classi che permettono di utilizzare la riflessione sono:
- Class
- Constructor
- Field
- Method
Class
Quando un programma è in esecuzione il sistema runtime di Java mantiene il tipo in runtime degli oggetti. Questa informazione è utilizzata dalla Java Virtual Machine per la selezione del metodo corretto. Per accedere a questa informazione si utilizza il metodo getClass() della classe Object che restituisce un'oggetto della classe Class.
Un esempio di come ottenere il tipo a runtime di un oggetto:
import java.util.LinkedList;
import java.util.List;
public class Riflessione {
public static void main(String[] arg){
try {
List<String> l = new LinkedList<String>();
Class c = l.getClass();
System.out.println(c);
String name = "java.util.ArrayList";
Class cl = Class.forName(name);
System.out.println(cl);
}
catch (ClassNotFoundException ex) {
System.out.println(ex.getMessage());
}
}
}
Dal codice si può notare che oltre ad utilizzare il metodo
getClass() della classe
Object per ottenere un oggetto della classe
Class, si può utilizzare anche il metodo statico
forName() della classe
Class passando a tale metodo una stringa che deve essere un nome valido di una classe o di una interfaccia, altrimenti il metodo genera un'eccezione verificata
ClassNotFoundException. Un altro metodo molto utile della classe
Class è
newIstance(), questo metodo utilizzato in combinazione con il metodo
forName() permette di creare un ogetto dal nome contenuto nella stringa che si passa al metodo
forName()
String name = "java.util.Date";
Object o=Class.forName(name).newInstance();
I due metodi utilizzati in combinazione come nell'esempio precedente possono generare due eccezioni verificate
InstantiationException e
IllegalAccessException.
Field,Method e Constructor
Le classi
Field,
Method e
Constructor sono tutte classi che fanno parte del pacchetto
java.lang.reflect queste classi descrivono ripettivamente i campi, i metodi e i costruttori di una classe.
La classe
Field ha un metodo
getType() che ritorna anch'esso un oggetto della classe
Class relativo al tipo del campo che descrive. La classe
Method ha alcuni metodi utilissimi tra i quali
getName() che ritorna un oggetto di tipo String che descrive il nome del metodo, il metodo
getParameterTypes()
che ritorna un array di oggetti ancora una volta di tipo Class che rappresenta il tipo dei parametri formali inseriti nel vettore secondo l'ordine in cui sono scritti nella signature del metodo, l'array può avere un numero di elementi uguale a 0, in questo caso significa che il metodo rispettivo non ha parametri.Il metodo
getReturnType() ritorna un oggetto di tipo Class che rappresenta il tipo di ritorno del metodo. Il metodo
getExceptionTypes() ritorna anch'esso un array di tipo Class e contiene tutte le eccezioni che il metodo specifica nella clausola
throws, la dimensione di questo array può essere 0 se il metodo non specifica eccezioni.
La classe
Constructor specifica tra i metodi anch'essa il metodo
getParameterTypes() ma in questo caso gli elementi dell'array che ritorna il metodo, identificano i parametri che il relativo costruttore richiede, naturalmente questo array di ritorno può avere 0 elementi.
Tutte le classi descritte specificano un metodo
getModifiers() questo metodo restituisce un intero con un insieme di bit di stato posti ad on/off per indicare i modificatori utilizzati per il rispettivo metodo, campo o costruttore a cui il metodo è applicato. I metodi della classe
Class getFields(),getMethods() e getConstructors() ritornano rispettivamente array dei campi, dei metodi e dei costruttori pubblici e tutti i membri pubblici della superclasse, metre i metodi
getDeclaredFields(),get DeclaredMethods() e getDeclaredConstructors() restituiscono array costitutiti da tutti gli attributi, metodi e costruttori dichiarati nella classe, anche i membri privati e protetti, ma non i membri della superclasse.