Ciao a tutti, ho una domanda sui generic, inizio subito postando il codice, così mi spiego meglio:
codice:
public abstract class Astratta1<E>{
protected Class<E> classeGen;
protected E istanza;
public abstract Class<E> getClasseGen();
public abstract boolean load(String file);
@SuppressWarnings("unchecked")
public E reloadInstanza(){
try{
istanza = (E)Class.forName(classeGen.getName()).newInstance();
}catch(ClassNotFoundException eccezione){
eccezione.printStackTrace();
}catch(InstantiationException eccezione){
eccezione.printStackTrace();
}catch(IllegalAccessException eccezione){
eccezione.printStackTrace();
}
return istanza;
}
}
codice:
public abstract class Astratta2<E extends Set<? extends Serializable>> extends Astratta1<E>{
@SuppressWarnings("unchecked")
@Override
public boolean load(String file){
boolean esito = true;
ObjectInputStream ois = null;
istanza = reloadInstanza();
try{
ois = new ObjectInputStream(new FileInputStream(new File(file)));
boolean cicla = true;
do{
try{
istanza.add((Serializable)ois.readObject());
ois.readObject();
}catch(EOFException eccezione){
cicla = false;
}catch(ClassNotFoundException eccezione){
eccezione.printStackTrace();
}
}while(cicla);
}catch(FileNotFoundException eccezione){
esito = false;
}catch(IOException eccezione){
esito = false;
}finally{
try{
if(ois != null){
ois.close();
}
}catch(Exception eccezione){
eccezione.printStackTrace();
}
}
return esito;
}
}
codice:
public class Concreta<V extends Serializable> extends Astratta2<HashSet<V>>{
@SuppressWarnings("unchecked")
@Override
public Class<HashSet<V>> getClasseGen(){
HashSet<V> prova = new HashSet<V>();
return (Class<HashSet<V>>)prova.getClass();
}
}
Allora le mie domande sono 2, una riguardante la seconda classe (Astratta2), e l'altra riguardante la terza (Concreta).
La prima domanda riguarda questa istruzione
codice:
istanza.add((Serializable)ois.readObject());
Perchè mi da errore?
"istanza" è di tipo "E", e come espresso nella dichiarazione della classe "E extends Set<? extends Serializable>" è un set che accetta solo oggetti che estendono Serializable, quindi se io dovessi castare il mio oggetto letto in Serializable, non vedo dove sia il problema.
Seconda domanda.
Nella classe "Concreta" ho dovuto implementare il metodo getClasseGen, perchè via reflection non potevo ricavarmi la classe di "V", in quanto a priori non so quante classi intermedie ci sono tra "Astratta1" e "Concreta" (nel mio caso c'è solo "Astratta2", ma in altre situazioni potrei avere ad esempio una classe "Astratta3", e così via). Non che sia un problema, se nella definizione di "Concreta" avessi messo extends Astratta2<HashSet> il mio codice sarebbe diventato semplicemente così
codice:
@Override
public Class<HashSet> getClasseGen(){
return HashSet.class;
}
Ma avendo dichiarato il tipo "V", non si può fare:
codice:
@Override
public Class<HashSet<V>> getClasseGen(){
return HashSet<V>.class;
}
Quindi ho dovuto definire un oggetto fittizio solo per poter ricavare da lui la classe.
La domanda alla fine è: ci sono altri metodi più corretti?
Spero di essermi spiegato meglio.
Grazie
Ciao