Newsgroup: it.comp.java
Titolo: Reflection: allocare i field di una classe

Ciao a tutti,
ho un problema semplice a descriversi ma al quale non riesco a trovare
una soluzione da due giorni!
Dunque, quello che vorrei è un metodo che, a partire da un certo obj,
invochi la new (di default) sui suoi membri.
Il codice è questo
Field[] fields = obj.getClass().getDeclaredFields();
for (Field field : fields) {
	String className = field.getType().toString();
	String classNameSub = className.substring(6, className.length());
	field.setAccessible(true);
        Class classDefinition = Class.forName(className);
	Object newObject = classDefinition.newInstance();
	//qui vorrei "assegnare" newObject a field.
}
Ovviamente assegnare direttamente.
Anche una strada del tipo
field = new fieldConstructor()
ma non sono riuscito a trovare il modo.
Insomma... ma si può fare? :)
Luigi

LuigiX (26/04/2010):

Quale sarebbe la tua intenzione in tutto ciò? Vorresti portare un
oggetto ad uno stato "iniziale" resettando tutti i membri?
A meno che l'oggetto non l'abbia scritto tu, non puoi assolutamente
sapere quali siano i valori corretti dei membri per considerare un
oggetto "appena inizializzato". E non puoi nemmeno essere certo che le
classi di tutti i membri dell'oggetto posseggano un costruttore di
default, peggio ancora se un membro è dichiarato come interfaccia o
classe astratta...
Spiega meglio cosa ti serve, si può sempre cercare una soluzione
migliore.
-- 
Scientology: se la conosci la eviti, se la conosci non ti uccide.
http://xenu.com-it.net
 - 
http://xenu.freewinds.cx
 - 
http://www.xenu.net
(per rispondere personalmente leva IlDitoDalCulo)
---> 09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0 <---

 migliore.
si chiaramente l'oggetto in oggetto (!!!) è un "mia" classe. Uso le
virgolette perchè in realtà estende
un mondo intero, ma i membri che voglio inizializzare sono tutti
"miei" e ne conosco l'insieme dei tipi.
Fondamentalmente sto cercando una soluzione allo Unit Testing del
framework ZK a cui nemmeno
gli autori stessi (del framework) hanno ancora dato una soluzione.
Sinteticamente: ho una classe che estende un "Composer" che
all'interno ha i riferimenti agli oggetti
(listbox, bottoni, combo ecc...) del frontend che, con una chiamata
alla "super" di un metodo della classe base,
viene fatto l'Autowiring (a patto che nel .java del composer gli
oggetti abbiano lo stesso id che nell' "html" che qui è un .zul).
Quindi di fatto c'è qualcuno che fa questa new.
Il problema è che per i Test devo reimplementare questo metodo che
alloca gli oggetti per me (che per la cronaca è doAfterCompose)
perchè ovviamente non si limita solo ad allocarli e quindi senza lo
strato di rendering esplode.
Per ora, mi sono limitato a fare un metodo di initTest() che fa la new
dei miei oggetti e la cosa funziona perfettamente.
Con una interfaccia/classe astratta ha fatto in modo che quantomeno ci
si ricordi di implementare questo metodo ma è tutto
codice "inutile" che serve solo ai Test Unit.
Ecco, spero di essermi spiegato un pò meglio :)
Anche se più in generale mi piacerebbe capire se il problema
"generico" è risolvibile o meno.
Grassie
LuigiX

LuigiX (27/04/2010):

Non conoscevo questo framework, mi documenterò appena avrò un po' più
di tempo.
Riprendendo il tuo codice, field.getType restituisce già un Class
perfettamente utilizzabile. Secondo me sarebbe meglio fare così:
-------------
Field[] fields = obj.getClass().getDeclaredFields();
for (Field field : fields) {
   field.setAccessible(true);
   Class<?> fieldClass=field.getType();
   Object newMember=fieldClass.newInstance();
   field.set(obj, newMember);
}
-------------
Field non è riferito "direttamente" al membro contenuto nell'oggetto,
più che altro rappresenta una *definizione* del membro: se guardi bene,
ottieni i field dalla *classe* del tuo oggetto, non direttamente
dall'oggetto.
La funzione Field.set fa esattamente quello che ti serve: imposta
sull'oggetto obj il membro rappresentato da field al valore riferito da
newMember.


 newMember.
FANTASTICO!!!
Non avevo ancora capito come funzionassero la get() e set() su Field,
ecco perchè pur avendoci provato mi era sfuggita la strada corretta.
E rivederlo ora mi sembra così banale che quasi mi vergogno :)
Grazieissimo, ora il mio mini-test-framework per ZK (che adoro... se
non ami jscript/html/jsp/jsf/ecc non si può non amarlo! :))
comincia a funzionare!!!
LuigiX