1. Generics
Generic Classes
Generics allow us to have flexible variable types within a class. Imagine you creating the following classes to contain a pair of objects:
class PairInt { int a, b; } class PairFloat { float a, b; } class PairString { String a, b; }
The above classes are identical besides the type of the internal fields. Thus, we can make the variable type generic (a "parameter"):
//This is read "class Pair generic on T": class Pair<T> { T a, b; }
The <T>
is the templated type above. Note that generics may sometimes also be called "type parameters" or "templates" in some languages.
Once this Pair class is defined, it can be used as so:
class Pair<T> { T a, b; } public class MyProgram { public static void main(String[] args) { //Using the pair class Pair<Integer> x = new Pair<Integer>(); x.a = 1; x.b = 41; Pair<String> y = new Pair<String>(); y.a = "First"; y.b = "Second"; System.out.println(x.a+x.b); System.out.println(y.a+y.b); } }
Notice that a variable type must be specified when instantiated Pairs. In addition, Java generics can only use object types, not primitives. This is a limitation due to how generics are implemented in Java.
Generics and Methods
Methods and constructors can use the type parameter as arguments or return types:
class Pair<T> { T first, second; public Pair(T first, T second) { this.first = first; this.second = second; } public T getFirst() { return first; } public T getSecond() { return second; } }
Generic Methods
Method declarations can specify their own parameter. This should be done before the return type of the method, such as the T here:
static <T> void fromArrayToCollection(T[] a, Collection<T> c) { for (T o : a) { c.add(o); } }
Wildcards
There are cases where you are using a generic class and do not care about the parameterized type. In these cases, you may use a question mark as the templated type:
void printCollection(Collection<?> c) { for (Object e : c) { System.out.println(e); } }
Thus, the method above will take a Collection with any parameter