Generics enable types
(classes and interfaces) to be parameters when defining classes, interfaces and methods. It is used in collection api, class, function.
Without generics, collection api, some classes, some functions will return Object, so that we need to downcast to proper class. If we use generics, it limits to a specified type, that is why it is type-safe.
- Stronger type checks at compile time (Type safe), thus reducing errors at runtime.
- Elimination of casts.
- Generic algorithms.
Methods that introduce their own type parameters.
- For static generic method, the type parameter section must appear before the method's return type.
public staic <K, V> boolean compare(Pair<K, V> p1,
Pair<K, V> p2) { /* ... */ }
- Class must be specified first.
Class A { /* ... */ }
interface B { /* ... */ }
interface C { /* ... */ }
class D <T extends A & B & C> { /* ... */ }
// compile-time error
class E <T extends B & A & C> { /* ... */ }
It represents an unknown type.
-
What is the different between Object and WildCard (?)
List<String> list = new ArrayList<String>(); List<Object> list2 = list; // compile error List<?> list3 = list; // works
Because, although
String
is aObject
,List<String>
is NOT aList<Object>
. However, everyList
is aList<?>
-
List<? extends A> list
: A or its subclass -
List<? super A> list
: A or its superclass -
extends
andsuper
cannot be used at the same timeNote: A can be class or interface
method(in, out)
-
An in variable is defined with an upper bounded wildcard, using
extends
.If a collection referenced by Collection<? extends ...>, it can be informally thought of as read-only (cannot store a new element or change an existing element without knowing the exact class when it is originally defined).
B extends A List<B> listB = new ArrayList<>(); List<? extends B> list = listB; list.add(new A)); // compile-time error
-
An out variable is defined with a lower bounded, using
super
. -
In the case where the "in" variable can be accessed using methods defined in the Object class, use an unbounded wildcard.
-
In the case where the code needs to access the variable as both an "in" and an "out" variable, do not use a wildcard.
-
Using a wildcard as a return type should be avoided.
Instead of creating new classes
- Replace all type parameters.
- Insert type casts.
- Generate bridge methods.