Se ... e ripeto se quella assegnazione fosse permessa allora si potrebbe inserire un String in un ArrayList<Object> che in realtà farebbe riferimento ad un ArrayList<Number>. E senza avere alcun errore/warning in compilazione!!Originariamente inviato da Hysoka
perdona la mia perseveranza, ma io non ci vedo niente di strano nel fare quel codice.
E tutti questi bei discorsi sui generics e sulla type-safety andrebbero a farsi friggere!!
Tutto il problema, a monte della proibizione di quell'assegnamento, è la "erasure". A runtime la collezione è solo un ArrayList e basta, non c'è scritto da nessuna parte (né all'interno della collezione né altrove) che è di Object o String o altro.
E per completare la discussione c'è da dire che si possono comunque combinare casini. Sfruttando il "raw type".
Ma almeno il compilatore emette un warning:codice:ArrayList<Number> numArr = new ArrayList<Number>(); ArrayList arr = numArr; // OK, nessun errore arr.add("pippo"); // warning!!!
warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.ArrayList
Come a dire: "guarda che stai facendo qualcosa che probabilmente può dare problemi". E poi appunto sono affari del programmatore ....
Certo ... questo sicuramente.Originariamente inviato da Hysoka
ma tutto quello che inserisco non lo posso usare come Object? O peggio, castarlo?
Ma qui non si stava parlando di cosa contengono le collezioni. Ma di come il wildcard (eventualmente con extends/super) fornisce una forma di "polimorfismo" sul tipo parametrico!!!codice:ArrayList<Number> numArr = new ArrayList<Number>(); // .... Object o = numArr.get(0);
Faccio un altro esempio: voglio realizzare un metodo che inserisce un certo numero di valori casuali interi in una collezione. Senza il wildcard si dovrebbe fare:
È chiaramente limitato ... posso solo passare un List<Integer> (es. ArrayList<Integer> o LinkedList<Integer>). Non posso passare un ArrayList<Number> o ArrayList<Object>.codice:public static void addRandom(List<Integer> lista, int count) { Random r = new Random(); while (count-- > 0) { lista.add(r.nextInt()); } }
Anche se a rigor di logica non sarebbe sbagliato (un Integer può stare benissimo in un ArrayList<Number> o ArrayList<Object>!!!).
Con un "lower bounded" wildcard:
Si può passare un ArrayList<Number> o ArrayList<Object>. Il 'super' indica proprio che il tipo della collezione accettato può essere Integer o un suo super-tipo.codice:public static void addRandom(List<? super Integer> lista, int count) { Random r = new Random(); while (count-- > 0) { lista.add(r.nextInt()); } }

Rispondi quotando