Bounded Generics in Java Programming
Bounded Generics in Java Programming
Ritwik Banerjee
rbanerjee@cs.stonybrook.edu
c© Ritwik Banerjee Bounded Generics in Java Programming 1/11
Type Parameters
I Generics allow us to use “types” (i.e., classes and interfaces) as
parameters when defining new classes, interfaces or methods.
I When we talk of parameters, there are two broad categories:
I Formal parameters used in method declaration.
I Type parameters so that we can re-use code with different types
of inputs.
I Inputs to formal parameters are values.
I Inputs to type parameters are types.
c© Ritwik Banerjee Bounded Generics in Java Programming 2/11
Bounded Type Parameters
I Sometimes, we may want to restrict the types that can be used
as type arguments in a parameterized type.
I An operation on numbers should only accept inputs that are
instances of java.lang.Number or its subclasses.
I This is where a bounded type parameter comes in.
I A type parameter that is restricted to a certain part of the Java
class hierarchy.
Expressing Restrictions . . . in terms of the Java class hierarchy
I A descendant (i.e., subclass) of Number
I C extends java.lang.Number
I An ancestor (i.e., superclass) of Number
I C super java.lang.Number
c© Ritwik Banerjee Bounded Generics in Java Programming 3/11
An example of type parameter restriction
public class Box
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
// Number is the upper bound of the parameter U
public void inspect(U u){
System.out.println(“T: ” + t.getClass().getName());
System.out.println(“U: ” + u.getClass().getName());
}
public static void main(String[] args) {
Box
integerBox.set(new Integer(10));
integerBox.inspect(“some text”); // Error!
}
}
c© Ritwik Banerjee Bounded Generics in Java Programming 4/11
Methods defined within bounds
public class NaturalNumber
private T n;
public NaturalNumber(T n) { this.n = n; }
public boolean isEven() { return n.intValue() % 2 == 0; }
}
I The isEven method invokes the intValue method defined in
the superclass Integer.
c© Ritwik Banerjee Bounded Generics in Java Programming 5/11
Multiple Bounds
I A type parameter can have multiple bounds
I In such cases, the type variable is a subtype of all the types
listed in the bound.
Class A { … }
interface B { … }
interface C { … }
I Then, we may write a bounded type of the form
class D
I If one of the bounds is a class, it must be specified first.
Otherwise there will be a compile-time error.
class D
c© Ritwik Banerjee Bounded Generics in Java Programming 6/11
Generic Methods with Bounded Type Parameters
A generic method that counts the number of elements in a set that
are greater than a specified element:
static
int count = 0;
for (T item : aSet)
if (item > t)
++count;
return count;
}
This code will fail to compile. WHY?
I The operator > applies only to primitive types (short, int, double,
long, float, byte, char). It cannot to be used to compare objects.
I To fix this, use a type parameter bounded by the Comparable
interface.
c© Ritwik Banerjee Bounded Generics in Java Programming 7/11
Generic Methods with Bounded Type Parameters
A generic method that counts the number of elements in a set that
are greater than a specified element:
static
int count = 0;
for (T item : aSet)
if (item > t)
++count;
return count;
}
This code will fail to compile. WHY?
I The operator > applies only to primitive types (short, int, double,
long, float, byte, char). It cannot to be used to compare objects.
I To fix this, use a type parameter bounded by the Comparable
interface.
c© Ritwik Banerjee Bounded Generics in Java Programming 7/11
Generic Methods with Bounded Type Parameters
A generic method that counts the number of elements in a set that
are greater than a specified element:
static
int count = 0;
for (T item : aSet)
if (item > t)
++count;
return count;
}
This code will fail to compile. WHY?
I The operator > applies only to primitive types (short, int, double,
long, float, byte, char). It cannot to be used to compare objects.
I To fix this, use a type parameter bounded by the Comparable
interface.
c© Ritwik Banerjee Bounded Generics in Java Programming 7/11
Generic Methods with Bounded Type Parameters
A generic method that counts the number of elements in a set that
are greater than a specified element:
static
int countGreater(Set
int count = 0;
for (T item : aSet)
if (item.compareTo(t) > 0)
++count;
return count;
}
c© Ritwik Banerjee Bounded Generics in Java Programming 8/11
Wildcards: ?
In Java, if a type parameter is unknown, it can represented by the
wildcard “?”. We can use wildcards to represent
I Unbounded type parameters,
I Type parameters with an upper bound, and
I Type parameters with a lower bound.
c© Ritwik Banerjee Bounded Generics in Java Programming 9/11
Upper Bounded Wildcards
I Say you want to write a method that works on List
List
I Clearly, you want to write a piece of code that works for Number
and its subclasses.
I This is where a wildcard should be used, but with an upper
bound:
extends Number>
static double sum(List extends Number> numbers) {
double sum = 0d;
for (Number aNumber : numbers)
sum += aNumber.doubleValue();
return sum;
}
c© Ritwik Banerjee Bounded Generics in Java Programming 10/11
Lower Bounded Wildcards
I In a different scenario, suppose you want to add integers to a list.
I And you want to write your code such that you can add your
integers to a list of Integers, or a list of Doubles, or a list of
Numbers.
I In this case, you want to work with anything that is a “supertype”
of Integer.
I Here, we want a wildcard with a lower bound:
super Number>
static void addTo(int i,
List super Integer> numbers) {
numbers.add(i);
}
c© Ritwik Banerjee Bounded Generics in Java Programming 11/11