Upload
stephan-janssen
View
1.593
Download
2
Embed Size (px)
DESCRIPTION
Slides from our BeJUG evening session on January 21st on Java Generics
Citation preview
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 1
Department of Computer Science
E. Steegmans K.U.Leuven
Java Generics
Overview
Basic concepts
Type erasure
Wild cards
Inheritance
Generic methods
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 2
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.
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 3
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); … }
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 4
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();
… }
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 5
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();
… }
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 6
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.
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 7
Generics: Advantages
Correctness Compile-time checks
Complexity Type casts
Readability Static information
Overview
Basic concepts
Type erasure
Wild cards
Inheritance
Generic methods
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 8
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.
}
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 9
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.
}
}
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 10
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
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 11
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
Type erasure
Wild cards
Inheritance
Generic methods
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 12
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>?
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 13
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
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 14
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
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 15
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
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 16
Overview
Basic concepts
Type erasure
Wild cards
Inheritance
Generic methods
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
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 17
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
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 18
The Composite Pattern
Overview Basic concepts
Type erasure
Wild cards
Inheritance
Generic methods
January 21, 2009 Generic Classes in Java
Eric Steegmans - K.U.Leuven 19
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