FabioJ ha scritto:
Mi sono ricordato che le interfacce non si possono istanziare e list e' un'interfaccia forse e' per questo che
List<String> NON è un sottotipo di List<Object>
Potrebbe essere giusta questa risposta ??
No, non è questo il motivo !!!
FabioJ ha scritto:
Vorrei capirlo eseguendo un programmino .
Non è tanto con un programmino .... cioè sì, puoi anche provare ma bisogna prima capire il concetto.
Gli array in Java sono "covarianti". Ovvero se S e T sono due tipi e
S è sottotipo di T, allora:
S[] è un sottotipo di T[] . Questo è quanto specifica il linguaggio Java.
In più c'è sapere il concetto basilare sugli array. Gli array sono completamente rappresentati a runtime. Quando istanzi un String[], all'interno dell'oggetto dell'array ci sono tutte le informazioni per tenere indicato che gli elementi sono di tipo
String.
Ora:
String[] sarr = new String[10];
Object[] oarr = sarr; // lecito e corretto
Adesso hai un array Object[] e a questo punto ti verrebbe da pensare: allora posso mettere in un elemento un Integer .... dopotutto Integer è-un Object .....
oarr[0] = new Integer(123); // NOOOOOO
Questa riga COMPILA perfettamente ma a runtime causa un
ArrayStoreException. L'ho detto prima: nell'oggetto array le informazioni ci sono tutte: "
i miei elementi sono di tipo String". E questa informazione VIENE controllata ad ogni assegnamento agli elementi. Se il tipo è appropriato, ok. Altrimenti ArrayStoreException.
Insomma, non è possibile "ravanare" il contenuto degli array con valori di tipo inappropriato, perché le informazioni sul tipo ci sono e vengono usate/applicate.
-----------------------------
I generics invece sono stati implementati per "erasure". Ovvero a runtime queste informazioni NON ci sono.
List<String> slist = new ArrayList<String>();
Nell'oggetto ArrayList NON c'è e non viene mantenuta a runtime alcuna informazione sul fatto che "è di String". I generics in sostanza "esistono" e sono controllati solo a livello di compilazione.
List<Object> olist = slist; // SE questo fosse possibile ......
olist.add(new Integer(123)); // QUI non c'è alcun controllo a runtime
E se olist = slist fosse possibile allora magari molto più avanti:
String str = slist.get(0); // FALLIREBBE perché l'oggetto è un Integer che non può essere castato a String.
Insomma, se olist = slist FOSSE possibile, allora sarebbe possibile "ravanare" il contenuto delle collezioni, perché non ci sono controlli (NON essendoci informazioni mantenute a runtime). E tutta la teoria dei generics andrebbe a farsi friggere ....
Per questo motivo è stato imposto che un List<S> NON è un sottotipo di List<T> anche se vale che S è un sottotipo di T.
Adesso c'è qualche "luce" in più? sull'argomento