Newsgroup: it.comp.java
Titolo: ricerca sottoclassi di una classe data

Ciao a tutti,
spero tanto che qualcuno di voi possa essermi d'aiuto perchè sto 
sbattendo la testa senza trovare soluzione. Il problema è il seguente.
Ho due classi, che chiamerò Gatto e Cane, entrambe sottoclassi di Animale.
Ho al necessità di istanziare una delle due classi in base ad un 
parametro (per esempio se tipo="cane" istanzierò un oggetto Cane) 
passato ad un altro oggetto. Quest'ultimo oggetto non è altro che un 
oggetto di tipo Factory (vedi il Factory pattern) .
Visto che le classi sottoclasse di Animale sono solo due potrei usare un 
"if", ma visto che tale progetto prevede la possibilità di upgrade, mi 
servirebbe qualcosa che dinamicamente mi restituisca l'elenco delle 
classi sottoclasse di Animale (se per esempio in un futuro volessi 
aggiungere altre categorie di animali).
Mi è stato suggerito di utilizzare la Reflaction, ma da quel che ho 
capito non è utile in quanto mi permette di risalire alla superclasse di 
una classe ma non da una classe alle sue sottoclassi.
Cercando e ricercando ho trovato soluzioni funzionanti per la ricerca 
delle sottoclassi solo attraverso l'analisi del classpath, ovvero 
tramite la scansione di tutte le directory e le jar; una volta trovati i 
nomi delle classi con la Reflaction è possibile trovare di quale classe 
sono sottoclasse.
Esistono altri metodi o questo è l'unico?
Vi ringrazio in anticipo,
Napmir

il 23.12.2010 14.43, Scrive 
news.fastwebnet.it
 65180416:

Secondo me non funziona neanche in tutti i casi, ad esempio se il 
classpath non è esplicitamente indicato nell'avvio della jvm, ad esempio 
se è quello indicato nel manifest, non hai modo di ricostruirlo.
Probabilmente potresti crearti un ClassLoader e man mano che viene 
richiamato il metodo addClass(Class c) dalla vm potresti chiederti se la 
classe e' di tuo interesse, nel qual caso te l'aggiungi ad una tua 
repository, ma non e' detto che tale metodo rispecchi la gerarchia 
dell'ereditarieta', per cui potrebbe essere che 
c.isAssignableFrom(Animale.class); ti tiri un bel ClassNotFoundexception 
perche' la classe Animale non e' ancora stata caricata.
-- 
Dr. Ugo Gagliardelli, Modena, Italy
Spaccamaroni andate a cagare/Spammers not welcome

 Esistono altri metodi o questo è l'unico?
diciamo che devi valutare il compromesso: andare a scandagliare il 
classpath a runtime al di la delle difficoltà tecniche è anche 
inutilmente oneroso, perché tutte le classi per essere analizzate 
vengono caricate in memoria e le definizioni delle classi non vengono 
mai scaricate. quindi ti ritroveresti una applicazione con un footprint 
in memoria esagerato per quello che deve fare.
il compromesso è, in sostanza, rinunciare al discovery dinamico e avere 
i nomi delle classi che ti interessano in una configurazione esterna. 
meglio ancora utilizzare un ioc container come quello di spring che ha, 
fra le innumerevoli features, quella di poterti "iniettare" in una 
collection tutte le istanze dello stesso tipo o che derivano dalla 
stessa classe/interfaccia.

 sottoclasse di Animale [...]
Potendo raggruppare le classi figlie nello stesso package:
1) dichiara il costruttore del padre "package private"
2) passa al metodo factory la parte variabile del nome della classe figlia
3) ricostruisci il "full class name" della classe figlia
4) usa la reflection.
-- 
ii 

 in memoria esagerato per quello che deve fare.
Puoi usa javassist evitando cosï¿œ di caricare le risorse, come spiegato qua
http://snipurl.com/1pwxy3

 
http://snipurl.com/1pwxy3
si vero, l'unico appunto che il link non è quello giusto per spiegare: 
si tratta di una utility (che non conoscevo) che *usa* javassist ma per 
andare in cerca di annotazioni.
comunque javassist è la risposta giusta (anche se imho valgono le 
considerazioni sull'opportunità di cercare dinamicamente queste classi 
invece di mapparne staticamente i nomi in file di 
configurazione/properties).


Beh, io userei comunque un'annotazione per specificare esplicitamente 
quali sono le vere classi animale che mi interessano, usando ad esempio 
quella libreria (che a usa volta usa javassist).
Se concesso, lo farei utilizzando Spring, o CDI.