You are on page 1of 22

Generics

Introduction
Generics enable types (classes and interfaces) to b
e parameters when defining classes, interfaces and
methods
Inputs to formal parameters are values, while the i
nputs to type parameters are types
public class Box<T>
T stands for "Type"
List<String> list = new ArrayList<String>();

Benefits
Stronger type checks at compile time
Enabling programmers to implement generic algori
thms
Elimination of casts
1. List list = new
ArrayList();
2. list.add("hello");
3. String s = (String)
list.get(0);

1. List<String> list = new


ArrayList<String>();
2. list.add("hello");
3. String s = list.get(0);

Type Parameter
Naming Conventions
E - Element
K- Key
N - Number
T - Type
V - Value
S,U,V etc. - 2nd, 3rd, 4th types

Diamond
Box<Integer> integerBox = new Box<Integer>();
Java SE 7 and later
Box<Integer> integerBox = new Box<>();

Multiple Type Parameters


public class OrderedPair<K, V>
OrderedPair<String, Integer> p1 = new OrderedPa
ir<String, Integer>("Even", 8);
OrderedPair<String, Integer> p1 = new OrderedPa
ir<>("Even", 8);
OrderedPair<String, Box<Integer>> p = new Order
edPair<>("primes", new Box<Integer>(...));

Generic Methods
Generic methods are methods that introduce their
own type parameters.
This is similar to declaring a generic type, but the ty
pe parameter's scope is limited to the method whe
re it is declared.
Static and non-static generic methods are allowed,
as well as generic class constructors.

Generic Methods
1.
2.
3.
4.
5.
6.

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());
}
}

7. Pair<Integer, String> p1 = new Pair<>(1, "apple")


;
8. Pair<Integer, String> p2 = new Pair<>(2, "pear");

Generic Methods
boolean same = Util.compare(p1, p2);
This feature, known as type inference, allows you t
o invoke a generic method as an ordinary metho
d, without specifying a type between angle brackets.

Generics, Inheritance, and Subtypes


1. Box<Number> box = new Box<Number>();
2. box.add(new Integer(10)); // OK
3. box.add(new Double(10.1)); // OK
Box<Integer> is not a subtype of Box<Number> ev
en though Integer is a subtype of Number.

Generics, Inheritance, and Subtypes

Generic Classes and Subtyping


ArrayList<E> implements List<E>, and List<E> exten
ds Collection<E>.
ArrayList<String> is a subtype of List<String>, whic
h is a subtype of Collection<String>.

A sample Collections hierarchy

So long as you do not vary the type argument, the


subtyping relationship is preserved between the typ
es.

Wildcards
The question mark (?), called the wildcard, represents an
unknown type
The wildcard can be used:
As the type of a parameter
Field
Local variable
Sometimes as a return type
The wildcard is never used:
As a type argument for a generic method invocatio
n
A generic class instance creatio

Upper Bounded Wildcards


1. public static double sumOfList(List<? extends Number> list) {
2.
double s = 0.0;
3.
for (Number n : list)
4.
s += n.doubleValue();
5.
return s;
6. }

7. List<Integer> li = Arrays.asList(1, 2, 3);


8. System.out.println("sum = " + sumOfList(li));
9. List<Double> ld = Arrays.asList(1.2, 2.3, 3.5);
10.System.out.println("sum = " + sumOfList(ld));

Lower Bounded Wildcards


1. public static void addNumbers(List<? super Integer> lis
t) {
2.
for (int i = 1; i <= 10; i++) {
3.
list.add(i);
4.
}
5. }
Work on List<Integer>, List<Number>, and List<Object>
anything that can hold Integer values.

Unbounded Wildcards
List<? > ----unknown type
An unbounded wildcard is a useful approach:
If you are writing a method that can be implemente
d using functionality provided in the Object clas
s.
When the code is using methods in the generic cla
ss that don't depend on the type parameter. For
example, List.size or List.clear.
In fact, Class<?> is so often used because most of
the methods in Class<T> do not depend on T.

Unbounded Wildcards
1. public static void printList(List<Object> list) {
2.
for (Object elem : list)
3.
System.out.println(elem + " ");
4.
System.out.println();
5. }
It prints only a list of Object instances; it cannot print List
<Integer>, List<String>, List<Double>, and so on, becaus
e they are not subtypes of List<Object>

Unbounded Wildcards
1. public static void printList(List<?> list) {
2.
for (Object elem: list)
3.
System.out.print(elem + " ");
4.
System.out.println();
5. }
Because for any concrete type A, List<A> is a subtype of
List<?>, you can use printList to print a list of any type

Restrictions on Generics
Cannot Instantiate Generic Types with Primitive Types
Pair<int, char> p = new Pair<>(8, 'a');
Cannot Create Instances of Type Parameters
public static <E> void append(List<E> list) {
E elem = new E();
Cannot Declare Static Fields Whose Types are Type Par
ameters
public class MobileDevice<T> {
private static T os;

Restrictions on Generics
Cannot Use Casts or instanceof with Parameterized Typ
es
public static <E> void rtti(List<E> list) {
if (list instanceof ArrayList<Integer>)
Cannot Create Arrays of Parameterized Types
List<Integer>[] arrayOfLists = new List<Integer>[2];
Cannot Create, Catch, or Throw Objects of Parameteriz
ed Type
// Extends Throwable indirectly
class MathException<T> extends Exception { /* ... */ }

Summary
1.
2.
3.
4.
5.

Thank You

You might also like