public class Coppia<P,S> { private final P primo; private final S secondo; public P getPrimo() { return primo; } public S getSecondo() { return secondo; } public Coppia(P primo, S secondo) { this.primo = primo; this.secondo = secondo; }}
In una classe generica i parametri di tipo appaiono nell'intestazione che dichiara la classe non nel costruttore!
Coppia<String, Integer> c = new Coppia<String, Integer>("Ciao", 1); assert c.getPrimo().equals("Ciao") && c.getSecondo().equals(1);
OK
Coppia<String,Integer> c = new Coppia("Ciao",1);
Warning! UncheckedWarning L'istruzione è legale ma genera un warning (non è detto che valga la Cast Iron Guarantee)
List<Integer> interi = Arrays.asList(1,2,3); List<String> stringhe = Arrays.asList("ciao","mondo"); assert interi.getClass() == stringhe.getClass();
I generics sono implementati tramite type erasure List<String> e List<Integer> a tempo di compilazione sono List
Type erasure →
public class Cella<T> { private final int id; private final T valore; public static int count = 0; public static synchronized int getCount() { return count;} public static synchronized int nextId() { return count++;} public int getId() { return id; } public T getValore() { return valore;} public Cella( T valore) { this.id = nextId(); this.valore = valore;} ...
Vediamo la classe all'opera
Cella<String>cs = new Cella<String>("ciao"); Cella<Integer> ci = new Cella<Integer>(1); assert cs.getId() == 0 && ci.getId() == 1 && Cella.getCount() == 2;
Il contatore è condiviso tra tutte le istanze della classe Cella
Java permette di annidare una classe dentro un'altra Se la classe esterna ha un parametro di tipo T:
public class Esterna<G> { ... private class Interna1{ Gg =null; ... } ... }
public class Esterna<G> { ... public G getPippo() { return new Interna2<G>().getPippo(); } public static class Interna2<H>{ public H getPippo() { ... } ...