Things you didn't know you can use in your Salesforce
BeJug.Org Java Generics
1. January 21, 2009 Generic Classes in Java
Department of Computer Science
Java Generics
E. Steegmans
K.U.Leuven
Overview
concepts
Basic
erasure
Type
Wild cards
Inheritance
Generic methods
Eric Steegmans - K.U.Leuven 1
2. January 21, 2009 Generic Classes in Java
Non-Generic Classes
No formal arguments involved in definitions of
classes and interfaces
Object is often used as the most general type for
variables, method arguments and return types
- Typical example: Container classes in Java API
Common practice before Java 1.5
Non-Generic Classes: Usage
List employees = new ArrayList();
Person albert = …;
Parrot filip = …;
employees.add(albert);
employees.add(filip);
// No compile-time checks nor runtime checks.
Person laurent = (Person) employees.get(1);
// Virtual machine throws ClassCastException.
Eric Steegmans - K.U.Leuven 2
3. January 21, 2009 Generic Classes in Java
Generics
Parameterized definitions of classes and
interfaces
Only reference types as formal arguments
- No other types such as integers, …
Convention: single letter arguments such as E
(element), T (type), K (key), …
Generic Classes
public class ArrayList
extends AbstractList
implements List, Cloneable, Serializable
{
public Arraylist();
public boolean add(Object elem);
public Object get(int index);
public boolean remove(Object o);
public boolean contains(Object o);
public Object[] toArray();
public Iterator iterator();
public List subList(int from, int to);
public boolean addAll(Collection c);
public boolean containsAll(Collection c);
public Class getClass();
public Object[] toArray(Object[] a);
…
}
Eric Steegmans - K.U.Leuven 3
4. January 21, 2009 Generic Classes in Java
Generic Classes
public class ArrayList<E>
{
public Arraylist();
public boolean add( E elem);
public E get(int index);
…
}
Generic Classes
public class ArrayList<E>
{
public Arraylist();
public boolean add(E elem);
public E get(int index);
public boolean remove(Object o);
public boolean contains(Object o);
public Object[] toArray();
…
}
Eric Steegmans - K.U.Leuven 4
5. January 21, 2009 Generic Classes in Java
Generic Classes
public class ArrayList<E>
extends AbstractList<E>
implements List<E>, Cloneable, Serializable
{
public Arraylist();
public boolean add(E elem);
public E get(int index);
public boolean remove(Object o);
public boolean contains(Object o);
public Object[] toArray();
public Iterator<E> iterator();
public List<E> subList(int from, int to);
…
}
Generic Classes
public class ArrayList<E>
extends AbstractList<E>
implements List<E>, Cloneable, Serializable
{
public Arraylist();
public boolean add(E elem);
public E get(int index);
public boolean remove(Object o);
public boolean contains(Object o);
public Object[] toArray();
public Iterator<E> iterator();
public List<E> subList(int from, int to);
public boolean addAll(Collection<? extends E> c);
public boolean containsAll(Collection<?> c);
public Class<? extends Object> getClass();
…
}
Eric Steegmans - K.U.Leuven 5
6. January 21, 2009 Generic Classes in Java
Generic Classes
public class ArrayList<E>
extends AbstractList<E>
implements List<E>, Cloneable, Serializable
{
public Arraylist();
public boolean add(E elem);
public E get(int index);
public boolean remove(Object o);
public boolean contains(Object o);
public Object[] toArray();
public Iterator<E> iterator();
public List<E> subList(int from, int to);
public boolean addAll(Collection<? extends E> c);
public boolean containsAll(Collection<?> c);
public Class<? extends Object> getClass();
public <T> T[] toArray(T[] a);
…
}
Generics: Usage
List<Person> employees =
new ArrayList<Person>();
Person albert = …;
Parrot filip = …;
employees.add(albert);
employees.add(filip);
// Compile-time checks.
Person laurent = employees.get(1);
// No type cast needed.
Eric Steegmans - K.U.Leuven 6
7. January 21, 2009 Generic Classes in Java
Generics: Advantages
Correctness
Compile-time checks
Complexity
Type casts
Readability
Static information
Overview
concepts
Basic
erasure
Type
cards
Wild
Inheritance
Generic methods
Eric Steegmans - K.U.Leuven 7
8. January 21, 2009 Generic Classes in Java
Type Erasure
The Java compiler removes all information related
to generic types
The Java Virtual Machine only knows of “raw types”
- All instances of all instantiations of a generic class (interface)
belong to the same class (interface)
Advantage: binary compatibility
The introduction of generics does not require any
changes to the Java Virtual Machine
- All Java applications can still run on the same virtual machine
Type Erasure: Consequences
public class GenericClass<T> {
private T[] elems = new T[12];
// At the time an array is created, the
// type of its elements must be supplied.
}
Eric Steegmans - K.U.Leuven 8
9. January 21, 2009 Generic Classes in Java
Type Erasure: Consequences
public class GenericClass<T> {
private T[] elems = new T[12];
public void someMethod(Object elem) {
if (elem instanceof T);
// No runtime type information (RTTI)
// available concerning generic args.
}
}
Type Erasure: Consequences
public class GenericClass<T> {
private T[] elems = new T[12];
public void someMethod(Object elem) {
if (elem instanceof T);
new T();
// No information concerning constructor
// of generic argument.
}
}
Eric Steegmans - K.U.Leuven 9
10. January 21, 2009 Generic Classes in Java
Type Erasure: Consequences
public class GenericClass<T> {
private T[] elems = new T[12];
public void someMethod(Object elem) {
if (elem instanceof T);
new T();
T theElement = (T) elem;
// Unchecked cast from Object to T.
}
}
Type Erasure: Conclusion
Java 1.4: Run-time type safety
Java programs may include attempts to assign values of
improper type
- Most attempts are already caught at compile-time
During the execution of a program, a variable can never
store a value of the wrong type
- The virtual machine checks the correctness of type casts
Eric Steegmans - K.U.Leuven 10
11. January 21, 2009 Generic Classes in Java
Type Erasure: Conclusion
Java 1.5: No runtime type safety for generic types
Without proper care
- Instantiations of generic classes may store elements of the
wrong type
- It is not impossible for a list of persons to store other objects such
as bank accounts, books and trees
- Instantiations of generic classes may return objects of a type
that differs from the return type
With proper care
- A generic class can make it impossible for clients to store
elements of the wrong type
- Methods of a generic class always return objects of the type
they promise
Overview
Basic concepts
erasure
Type
cards
Wild
Inheritance
Generic methods
Eric Steegmans - K.U.Leuven 11
12. January 21, 2009 Generic Classes in Java
Polymorphism in Java 1.4
If S is a subtype of T, an object of type S can be
assigned to a variable of type T
Objects of type Woman and objects of type Man can be
assigned to variables of type Person
Can we assign an array of type S[] to a variable
of type T[]
Polymorphism in Java 1.5
Can we assign an object of type G<S> to a
variable of type G<T>?
Assuming G is a generic class or interface, and S is a
true subtype of T
- Can we assign an object of type List<Woman> to a variable of
type List<Person>?
Eric Steegmans - K.U.Leuven 12
13. January 21, 2009 Generic Classes in Java
Unbounded Wild Cards
A variable of type G<?> is a supertype for any
instantiation of the generic class or interface G
A variable of type List<?> can be assigned objects of
type List<Person>, List<Integer>, ...
The object referenced by a variable of type G<?>
is more or less read-only
Methods of G<E> with arguments of type E cannot be
invoked against variables of type G<?>
- Invocations of methods without arguments of type E may still
cause state changes
Variables of type G<?> act as if the class or interface is
instantiated with Object
- Invocations of methods declared to return an object of type E,
return an object of type Object
Bounded Wild Cards
A variable of type G<? extends X> is a super-
type for instantiations with type X or subtype of X
A variable of type List<? extends Person> can be
assigned objects of type List<Man>, List<Woman>, ..
This type of wild card specifies an upper bound for
actual types at the time of instantiation
The object referenced by a variable of type
G<? extends X> is to some extent read-only
Methods of G<E> with arguments of type E cannot be
invoked against variables of type G<? extends X>
Variables of type G<? extends X> act as if the class
or interface is instantiated with X
Eric Steegmans - K.U.Leuven 13
14. January 21, 2009 Generic Classes in Java
Bounded Wild Cards
A variable of type G<? super X> is a supertype
for any instantiation with type X or supertype of X
A variable of type List<? super Man> can be
assigned objects of type List<Man>, List<Person>
This type of wild card specifies a lower bound for actual
types at the time of instantiation
The object referenced by a variable of type
G<? super X> is to some extent write-only
Methods of G<E> with actual argument of type E can
only be invoked with actual arguments of type X
Invocations of methods declared to return an object of
type E, return an object of type Object
Raw Types
A variable of type G is a supertype for any
instantiation of the generic class or interface G
A variable of type List can be assigned objects of type
List<Account>, List<Person>
Be careful in approaching generic instantiations by
means of raw types!
Methods of G<E> with actual argument of type E can be
invoked against variables of type G
- The Java compiler only issues warnings for possible type
mismatches
Invocations of methods declared to return an object of
type E, return an object of type Object
Eric Steegmans - K.U.Leuven 14
15. January 21, 2009 Generic Classes in Java
Generic Arguments: Bounds
A generic class or interface G<T extends C>
can only be instantiated with C or a subtype of C
All methods of class or interface C can be invoked
against variables of type T
Multiple bounds on generic arguments are
possible as in G<T extends X & Y>
Wild Cards: Conclusion
Wild cards are needed in polymorphic
assignments only because of type erasure
Other languages such as C++, C# and Eiffel do not
need wild cards in variable declarations
Approaching generic instantiations with raw types is
asking for (big) problems
Wild cards are useful in specifying restrictions on
generic arguments
Eric Steegmans - K.U.Leuven 15
16. January 21, 2009 Generic Classes in Java
Overview
Basic concepts
Type erasure
cards
Wild
Inheritance
methods
Generic
Generic Subclasses
A generic class may extend a single class and
may implement several interfaces
Superclasses and superinterfaces may be instantiations
of generic classes, resp. generic interfaces
- Typically, formal arguments of the generic subclass are used to
instantiate generic superclasses and superinterfaces
A generic interface may extend several interfaces
Eric Steegmans - K.U.Leuven 16
17. January 21, 2009 Generic Classes in Java
Polymorphism
If S<E> inherits from T<E>, can we assign an
object of type S<C> to a variable of type T<C>?
Can an object of type SortedSet<Integer> be
assigned to a variable of type Set<Integer>?
Frameworks
Generics (can) considerably improve the quality of
frameworks
Unfortunately they may also considerably increase the
complexity of frameworks
Wild cards are not powerful enough to express all
restrictions
Eric Steegmans - K.U.Leuven 17
18. January 21, 2009 Generic Classes in Java
The Composite Pattern
Overview
Basic concepts
Type erasure
Wild cards
Inheritance
methods
Generic
Eric Steegmans - K.U.Leuven 18
19. January 21, 2009 Generic Classes in Java
Generic Methods: Definition
A generic method is parameterized in one or more
types
As for generic classes, generic methods can only be
parameterized in reference types
- The generic parameters precede the return type of the method
Generic arguments can express dependencies
among types of ordinary formal arguments
Bounded wildcards in both directions are used for that
purpose
The actual types of generic methods are derived
from their actual arguments
The compiler rejects invocations if no matching type is
available
Eric Steegmans - K.U.Leuven 19