Le sezione dei type parameters, delimitata da <>, segue il nome della classe. Essa specifica i type parameters (anche detti type variables) T1, T2, .....Tn.
La generic class declaration di Box diventa:
/** * Generic version of the Box class. * @param<T> the type of the value being boxed*/publicclassBox<T>{ // T stands for "Type"privateT t;publicvoidset(Tt){this.t= t;}publicTget(){return t;}}
Come si può vedere, tutte le occorrenze di Object sono sostituite da T . Un tipo variabile può essere qualsiasi tipo non primitivo: qualsiasi tipo classe, tipo interface, tipo array, o anche un altro tipo parametrico.
Per riferirsi a un generic Box nel codice, bisogna eseguire una generic type invocation, che sostituisce il tipo generico T con il tipo concreto, ad esempio Integer:
Un altro esempio, di definizione di tipo parametrico:
Ora l'istanziazione del tipo parametrico:
Si può sostituire al parametro di un tipo parametrico (es: T ) con un altro tipo parametrizzato ad esempio List<Integer>, ad esempio:
Generic methods
Generic methods sono metodi che introducono anche loro tipo parametrici. Sono simili alla dichiarazionedi un tipo parametrico, ma lo scope del tipo parametrico è limitata al metodo dove è dichiarato. Sono parmessi metodi parametrici, di tipo statico e non statico, così come costruttori generici.
La sintassi per un metodo generico include la lista det tipi parametrici prima del tipo di ritorno del metodo.
La classe Util contiene un metodo parametrico compare tra due Pair object:
Per invocare il metodo:
Il tipo è stato provvisto esplicitamente (<Integer, String>). Generalment si può anche evitare, il compilatore riesce a inferire i tipi cge sono necessari:
public interface Pair<K, V> {
public K getKey();
public V getValue();
}
public class OrderedPair<K, V> implements Pair<K, V> {
private K key;
private V value;
public OrderedPair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() { return key; }
public V getValue() { return value; }
}
Pair<String, Integer> p1 = new OrderedPair<String, Integer>("Even", 8);
Pair<String, String> p2 = new OrderedPair<String, String>("hello", "world");
OrderedPair<String, Box<Integer>> p = new OrderedPair<>("primes", new Box<Integer>(...));
public class Util {
public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
return p1.getKey().equals(p2.getKey()) &&
p1.getValue().equals(p2.getValue());
}
}
public class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public void setKey(K key) { this.key = key; }
public void setValue(V value) { this.value = value; }
public K getKey() { return key; }
public V getValue() { return value; }
}
Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, String> p2 = new Pair<>(2, "pear");
boolean same = Util.<Integer, String>compare(p1, p2);
Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, String> p2 = new Pair<>(2, "pear");
boolean same = Util.compare(p1, p2);