By providing a type argument per type parameter.
The type argument list is a comma separated list that is delimited by angle brackets and follows the type name. The result is a so-called parameterized type.
example of a generic type:
class Pair<X, Y> {
private X first;
private Y second;
}
example of a concrete parameterized type:
public void printPair(Pair<String, Long> pair) {}
and:
Pair<String, Long> pair = new Pair<String, Long>("maxsize", 1024L);
wildcard instantiations
In addition to concrete instantiation there so-called wildcard instantiations. They do not have concrete types as arguments, but so-called wildcards. A wildcard is a syntactic construct with a ? that denotes not just one type, but a family of types.
Example of a wildcard parameterized type:
public void printPair(Pair<?, ?> pair) {
....
}
Pair<?, ?> pair = new Pair<String, Long>("maximum", 1024L);
printPair(pair);
raw types
It is permitted to leave out the type arguments altogether and not specify type arguments at all. A generic type without type arguments is called raw type and is only allowed for reasons of compatibility with non-generic Java code.
Use of raw types is discouraged.