Chapter 7b Generics
1
Objectives
To know the benefits of generics (§19.1).
To use generic classes and interfaces (§19.2).
To declare generic classes and interfaces (§19.3).
To understand why generic types can improve reliability and readability
(§19.3).
To declare and use generic methods and bounded generic types (§19.4).
2
Raw Type
Raw type – elements are of type Object.
ArrayList list = new ArrayList();
This is roughly equivalent to
ArrayList<Object> list = new ArrayList<>();
3
Raw Type is Unsafe
public class ShowUncheckedWarning {
public static void main(String[] args) {
java.util.ArrayList list =
new java.util.ArrayList();
list.add("123");
list.add(555);
System.out.println ((int)list.get(0) +
(int)list.get(1));
}
}
Wrongly added an integer as String. Compiler
won't detect the error, therefore using raw type
is unsafe.
4
Generic Type is Safe
public class ShowUncheckedWarning {
public static void main(String[] args) {
java.util.ArrayList<Integer> list =
new java.util.ArrayList<>();
`
list.add("123");
list.add(555);
System.out.println (list.get(0) +
list.get(1));
}
}
Ensure only integers are added into list, safe.
Compiler detects the error.
5
Avoiding Unsafe Raw Types
Avoid unsafe raw types whenever possible.
For example, use
new ArrayList<ConcreteType>()
Instead of
new ArrayList();
6
What is Generics?
Generics is the capability to parameterize types.
With this capability, you can define a class or a
method with generic types that can be substituted
using concrete types by the compiler.
For example, you may define a generic stack
class that stores the elements of a generic type.
From this generic class, you may create a stack
object for holding strings and a stack object for
holding numbers. Here, strings and numbers are
concrete types that replace the generic type.
7
Why Generics?
The key benefit of generics is to enable errors to
be detected at compile time rather than at
runtime.
• A generic class or method permits you to specify
allowable types of objects that the class or method
may work with. If you attempt to use the an
incompatible object, a compile error occurs.
Another benefit of generics is no casting is
required when getting element from ArrayList or
other Java collections.
8
Raw Type Generic Type
package java.lang; package java.lang;
public interface Comparable { public interface Comparable<T> {
public int compareTo(Object o) public int compareTo(T o)
} }
(a) Prior to JDK 1.5 (b) JDK 1.5
Runtime error Generic Instantiation
Comparable c = new Date(); Comparable<Date> c = new Date();
System.out.println(c.compareTo("red")); System.out.println(c.compareTo("red"));
(a) Prior to JDK 1.5 (b) JDK 1.5
Improves reliability
Compile error
9
No Casting Needed
No casting is required when getting element from
ArrayList or other Java collections.
// Raw
ArrayList list = new ArrayList();
list.add(123);
list.add(555);
System.out.println ((int)list.get(0) + // casting is required
(int)list.get(1));
// Generics
ArrayList<Integer> list = new ArrayList<>();
list.add(123);
list.add(555);
System.out.println (list.get(0) + // no casting
list.get(1));
10
Declaring Generic Classes
To declare a generic class, you place the generic
type <T> immediately after the class name.
// Raw
class Box {
private Object object;
public Box (Object object) { this.object = object; }
public Object get() { return object; }
}
// Generic
class Box <T> {
private T object;
public Box (T object) { this.object = object; }
public T get() { return object; }
}
11
Using Generic Classes
To use a generic class, place angle brackets <T>
immediately after the class name.
Box<Integer> b1 = new Box<>(123); // for Integer
int n = b1.get();
Box<String> b2 = new Box<>("Hello"); // for String
String s = b2.get();
12
Declaring Generic Stack
Study GenericStack.java.
GenericStack
13
Generic Methods
To declare a generic method, you place the generic type
<E> immediately before the return type in the method
header.
Example - print all elements in list:
// Raw
public static void print(Object[] list) {
for (int i = 0; i < list.length; i++)
System.out.println(list[i]);
}
// Generic
public static <E> void print(E[] list) {
for (int i = 0; i < list.length; i++)
System.out.println(list[i]);
}
14
Bounded Generic Type
When declaring a generic class or method, we may want
to limit the generic type to a class or its subclasses.
This kind of generic type is specified as a subtype
(subclass) of another type. Such a generic type is called
bounded.
For example, the equalArea method below limits
generic type E to subclasses of GeometricObject
only.
public static <E extends GeometricObject> boolean equalArea (
E object1, E object2) {
return object1.getArea() == object2.getArea();
}
15
Bounded Generic Type, cont.
Recall that Rectangle class and Circle class are
subclass of GeometricObject.
We can then use the equalArea method to check
whether a Rectangle object and a Circle object have the
same area.
public static void main(String[] args ) {
Rectangle rectangle = new Rectangle(2, 2);
Circle circle = new Circle (2);
System.out.println ("Same area? " +
equalArea(rectangle, circle));
}
16
Comparable Generic Method
If we want to limit a method to compare objects of a
generic type using compareTo method, the generic
type must extend the Comparable interface.
/** Return the maximum between two objects */
public static <E extends Comparable<E>> E max(E o1, E o2) {
if (o1.compareTo(o2) > 0)
return o1;
else
return o2;
}
...
// invoke max() method
max("Welcome", "Hello");
max(44, 23);
17