Newsgroup: it.comp.java
Titolo: Reflection

Salve a tutti.
Sto realizzando una applicazione RMI per la quale avrei bisogno che il
Server riesca ad estrarre i valori dei campi della classe che gli viene
passata attraverso una chiamata remota.
Riesco ad estrarre il tipo dei campi: attraverso la funzione
java.lang.Class.getFields() mi restituisce un array di oggetti Field
della classe in questione; poi attraverso il metodo getType riesco ad
ottenere il tipo, ma quello che mi serve e' conoscere anche il valore.
Grazie anticipatamente.
Giovanni

 ottenere il tipo, ma quello che mi serve e' conoscere anche il valore.
una volta saputo il tipo penso ti basti fare un cast dinamico a quel 
tipo ed accedere ai suoi metodi getter....
Kali

 wrote in
news:3C18CF82...@arena.sci.univr.it
: 

Usi gli altri metodi "get", che hanno come parametro l'oggetto da cui
devi estrarre il valore: getBoolean(), getByte(), etc e getObject() per
tutti gli altri tipi (piu' un cast, ovviamente, se serve). 
Ovviamente l'oggetto dev'essere di tipo compatibile con la Class da cui
hai recuperato il Field. 
-- 
Life's something u don't get out alive..
ObjectZone - 
http://space.tin.it/computer/csadun


ai quei metodi get, cosa deve essere passato tra parentesi?
Cioe':
Field[] array = "classe".getFields();
// Se l'oggetto e' un Int
int prova =  (array[i].getType())array[i].getInt(????);
Grazie per l'aiuto.
Giovanni

 int prova =  (array[i].getType())array[i].getInt(????);
No, (array[i].getType())array[i] non e' Java :) - il cast e' una nozione
che si applica a tempo di compilazione, non runtime. 
Se la tua classe MiaClasse ha un membro pippo di tipo intero, usi
Class cls = Class.forName("MiaClasse");
Field f = cls.getField("pippo");
Object obj = ....un oggetto di tipo MiaClasse....
int valoreDiPippo = f.getInt(obj);


 ObjectZone - 
http://space.tin.it/computer/csadun
Il client trasferisce al Server un'oggetto di tipo MiaClasse che
implementa Entry (interfaccia).
public MiaClasse implements Entry 
	String name;
	String surname;
	public MiaClasse(Strign name, String surname)
 
this.name
=name;
		this.surname=surname;
 
Il Server sa che ricevera' un oggetto che implementa la classe Entry, ma
non sa le caratteristiche (nome, membri, ecc.) di quella classe.
Percio' il Server non conosce i membri (nome e tipo) della classe
MiaClasse.
Supponiamo che il Client invii al Server una Entry del tipo
MiaClasse("Giovanni", "Perbellini")
Non sapendo le sue caratteristiche ho pensato di fare (il server riesce
ad estrapolare un oggetto di tipo Entry e lo assegno a entry1):
Entry entry1;
Field[] array = entry1.getClass().getFields();
Adesso io conosco i membri ma non so come fare a estrapolare i valori
(perche' il Server non li conosce)!
Per dirla tutta, il Server dovra' verificare se tale oggetto Entry e'
presenta in una tabella presente sul Server, e deve confrontare campo
per campo, l'oggetto passato dal Client con quelli presenti in tabella
per vedere se ne esiste uno uguale.
Grazie per l'aiuto
Giovanni Perbellini

 per vedere se ne esiste uno uguale.
Assumo tu voglia fare il controllo con una select SQL, verificando se
ritorna o meno valori. E immagino tu abbia deciso come fare mapping tra
*nomi* di membri della classe e *nomi* di colonne SQL (il caso semplice
e' quello per cui il nome della colonna e' uguale a quello del campo :). 
Cio' detto, e' semplice: quello che devi avere ; dato un oggetto obj,
Field [] fieldsArray = obj.getClass().getDeclaredField();
StringWriter whereClause = new StringWriter();
PrintWriter pw = new PrintWriter(whereClause);
// Costruisce una clausola SQL "where" coi valori dei membri di obj
for(int i=0;i<fieldsArray;i++) {
    String columnName = fieldsArray[i].getName(); 
    	    	    	    	    	// (O qualunque trasformazione ti serva)
    Object value = fieldsArray[i].get(obj);
    // Converte valori boolean java da true/false a "1"/"0"
    if (fieldsArray[i].getType() == Boolean.TYPE) 
    	    	value=("true".equals(value) ? "1" : "0");
    pw.print(columnName+" = ");
    if (requiresQuotes(columnName))
    	    	pw.print("'"+value+"'");
    else pw.print(value);
    if (i<fieldsArray-1) pw.print(" and ");
}
String statement = "select count(*) from "+nomeTabella+" where
"+whereClause; 
..esegui statement..
Il metodo 'requiresQuotes' deve ritornare true o false a seconda che il
tipo SQL sia CHAR, VARCHAR etc (e quindi richieda quoting in SQL) oppure
numerico. 
Questa soluzione ignora del tutto il *tipo* - si basa sul fatto che per
le classi standard, associate ai tipi primitivi (e ovviamente a String),
toString() (invocata da pw.print(value) e' overriden in modo da
ritonrnare la denotazione in stringa del valore (ho comunque illustrato
un possibile uso di getType() trattando "boolean" come caso speciale). 
Nel caso ti servano altri "trattamenti speciali", avrai una serie di
if (fieldsArray[i].getType() == String.class) { ... }
else if (fieldsArray[i].getType() == Integer.TYPE) { ... }
else ...
Ovviamente, cio' si applica a tipi standard. Se vuoi trattare nello
stesso modo tipi (classi) i cui membri possono avere tipi non standard,
e' possibile, ma e' piu' complesso (devi analizzare ricorsivamente i vari
tipi e definire una politica di mapping su tabelle). 
Infine, puoi voler dare un'occhata a CMaker, che mappa tabelle in oggetti
esattamente usando la reflection, a 
http://space.tin.it/computer/csadun/software/cmaker
o
http://sourceforge.net/projects/cmaker/
I sorgenti contengono probabilmente gia' tutto quello che ti serve,
compreso un type mapper tra SQL e Java. -- 


Grazie mille, quella "get" mi ha risolto un bel problemino!
Giovanni.