BeJug.Org Java Generics

19
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

description

Slides from our BeJUG evening session on January 21st on Java Generics

Transcript of BeJug.Org Java Generics

Page 1: BeJug.Org   Java Generics

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

Page 2: BeJug.Org   Java Generics

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.

Page 3: BeJug.Org   Java Generics

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

Page 4: BeJug.Org   Java Generics

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

… }

Page 5: BeJug.Org   Java Generics

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

… }

Page 6: BeJug.Org   Java Generics

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.

Page 7: BeJug.Org   Java Generics

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

Page 8: BeJug.Org   Java Generics

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.

}

Page 9: BeJug.Org   Java Generics

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.

}

}

Page 10: BeJug.Org   Java Generics

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

Page 11: BeJug.Org   Java Generics

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

Page 12: BeJug.Org   Java Generics

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>?

Page 13: BeJug.Org   Java Generics

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

Page 14: BeJug.Org   Java Generics

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

Page 15: BeJug.Org   Java Generics

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

Page 16: BeJug.Org   Java Generics

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

Page 17: BeJug.Org   Java Generics

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

Page 18: BeJug.Org   Java Generics

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

Page 19: BeJug.Org   Java Generics

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