SlideShare a Scribd company logo
1 of 171
Download to read offline
Yann-Gaël Guéhéneuc
Département de génie informatique et de génie logiciel
This work is licensed under a Creative
Commons Attribution-NonCommercial-
ShareAlike 3.0 Unported License
Java
Generics
yann-gael.gueheneuc@polytmtl.ca
Version 1.1
2014/05/12
2/171
Any questions/comments are welcome at
yann-gael.gueheneuc@polymtl.ca
Source code available at
http://www.ptidej.net/tutorials/javagenerics
3/171
2013/03/22 – v1.0 – First version of the slides
2013/04/19 – v1.0.1 – Fixed some typos
2014/05/12 – v1.1 – Added example of mixing objects
Cited PECS explanations
Added more generated bytecodes
Fixed some typos
4/171
Problem
 Sorting lists does not and should not depend
on the type of the elements stored in the list
import java.util.List;
public interface ISort {
public List sort(final List aList);
}
5/171
Problem
 Sorting lists does not and should not depend
on the type of the elements stored in the list
Problem: elements may not be comparable
Solution: generic typing with Comparable
6/171
Problem
 Sorting lists assumes (and is sure) that the
elements stored in the list are comparable
import java.util.List;
public interface ISort<E extends Comparable<E>> {
public List<E> sort(final List<E> aList);
}
7/171
Outline
 History
 Problem
 Special Case
 General Definitions
 Generics Definitions
– Parametric
Polymorphism
– Other Bounded
Parametric
Polymorphisms
 When to Use Generics
 How to Use Generics
 Caveats with Generics
 Reflecting on Generics
 Conclusion
 Few References
8/171
Outline
 History
 Problem
 Special Case
 General Definitions
 Generics Definitions
– Parametric
Polymorphism
– Other Bounded
Parametric
Polymorphisms
 When to Use Generics
 How to Use Generics
 Caveats with Generics
 Reflecting on Generics
 Conclusion
 Few References
9/171
History
 1983: Reynolds formalises the parametricity
theorem, called abstraction theorem
– Functions with similar types have similar
properties
John C. Reynolds
*1935
John C. Reynolds ; “Types, abstraction, and parametric polymorphism” ; Information
Processing ; pp. 513–523, North Holland, 1983.
10/171
History
 Parametric polymorphism
– Expressiveness
– Type-safety
• First implementation in ML in 1989 (1976?)
append: [a]  [a]  [a]
Robin Milner, Robert Harper, David MacQueen, and Mads Tofte ; “The Definition Of Standard
ML” ; The MIT Press, 1997.
11/171
History
 Parametric polymorphism
– Expressiveness
– Type-safety
• First implementation in ML in 1989 (1976?)
append: [a]  [a]  [a]
Robin Milner, Robert Harper, David MacQueen, and Mads Tofte ; “The Definition Of Standard
ML” ; The MIT Press, 1997.
Explicit parametric
polymorphism
12/171
History
 1988: David Musser and Alexander
Stepanov define the concept of generic
programming
– Abstractions from examples of algorithms and
data structure
– Concept of “concept”
David R. Musser and Alexander A. Stepanov ; “Generic Programming” ; International
symposium on Symbolic and Algebraic Computation, pp. 13-25, ACM Press, 1988.
Alexander Stepanov
*1950
David Musser
*c.1945
13/171
History
“Generic programming is about abstracting
and classifying algorithms and data
structures. […] Its goal is the incremental
construction of systematic catalogs of useful,
efficient and abstract algorithms and data
structures.”
—Alexander Stepanov
14/171
History
 Generic programming
– Theory of iterators
– Independent of implementation
• C++ Standard Template Library (STL)
const ::std::vector<Foo>::iterator theEnd = theContainer.end();
for ( ::std::vector<Foo>::iterator i = theContainer.begin();
i != theEnd;
++i ) {
Foo &cur_element = *i;
// Do something…
}
15/171
History
 1994: the GoF defines parameterized types
“Also known as generics (Ada, Eiffel) and
templates (C++)”
“A type that leaves some constituent types
unspecified. The unspecified types are supplied
as parameters at the point of use.”
16/171
History  19771980: Ada
– 2005: generic container library
 1985: Eiffel
Bertrand Meyer ; Object-Oriented Software
Construction ; Prentice Hall, 1988.
 1991: C++
http://www.stroustrup.com/hopl2.pdf
– 1994: STL (under Stepanov’s guidance)
 2004: Java
– Type erasure
 2005: C#
– Reified generics
17/171
Outline
 History
 Problem
 Special Case
 General Definitions
 Generics Definitions
– Parametric
Polymorphism
– Other Bounded
Parametric
Polymorphisms
 When to Use Generics
 How to Use Generics
 Caveats with Generics
 Reflecting on Generics
 Conclusion
 Few References
18/171
Problem
“Implement generic algorithms that work on
a collection of different types”
—The Java Tutorials, Oracle
http://docs.oracle.com/javase/tutorial/java/generics/why.html
19/171
Problem
 Sorting lists does not and should not depend
on the type of the elements stored in the list
import java.util.List;
public interface ISort {
public List sort(final List aList);
}
20/171
Problem
 Sorting lists does not and should not depend
on the type of the elements stored in the list
Problem: elements may not be comparable
Solution: generic typing with Comparable
21/171
Problem
 Sorting lists does not and should not depend
on the type of the elements stored in the list
import java.util.List;
public interface ISort<E extends Comparable<E>> {
public List<E> sort(final List<E> aList);
}
22/171
Outline
 History
 Problem
 Special Case
 General Definitions
 Generics Definitions
– Parametric
Polymorphism
– Other Bounded
Parametric
Polymorphisms
 When to Use Generics
 How to Use Generics
 Caveats with Generics
 Reflecting on Generics
 Conclusion
 Few References
23/171
Special Case
package net.ptidej.generics.java;
public class Example1 {
public static void main(final String[] args) {
final Object[] arrayOfObjects = new Object[10];
final String[] arrayOfStrings = new String[20];
System.out.println(arrayOfObjects.length);
System.out.println(arrayOfStrings.length);
System.out.println(arrayOfObjects[0]);
System.out.println(arrayOfStrings[2]);
System.out.println(arrayOfObjects.clone());
System.out.println(arrayOfStrings.toString());
}
}
24/171
Special Case
 Array are (often) predefined generic types
final Object[] arrayOfObjects = new Object[10];
final String[] arrayOfStrings = new String[20];
25/171
Special Case
 Array are (often) predefined generic types
final Object[] arrayOfObjects = new Object[10];
final String[] arrayOfStrings = new String[20];
Any type can go here
26/171
Special Case
 Every new array instantiates a new concrete
type (or reuse an existing concrete type)
27/171
Special Case
 Every new array instantiates a new concrete
type (or reuse an existing concrete type)
New concrete type
(pseudo-type in Java)
28/171
Special Case
 Syntax and semantics built in the compiler
System.out.println(arrayOfObjects.length);
System.out.println(arrayOfStrings.length);
System.out.println(arrayOfObjects[0]);
System.out.println(arrayOfStrings[2]);
System.out.println(arrayOfObjects.clone());
System.out.println(arrayOfStrings.toString());
29/171
Special Case
 Syntax and semantics built in the compiler
Pseudo-field
System.out.println(arrayOfObjects.length);
System.out.println(arrayOfStrings.length);
System.out.println(arrayOfObjects[0]);
System.out.println(arrayOfStrings[2]);
System.out.println(arrayOfObjects.clone());
System.out.println(arrayOfStrings.toString());
30/171
Special Case
 Syntax and semantics built in the compiler
Pseudo-field
System.out.println(arrayOfObjects.length);
System.out.println(arrayOfStrings.length);
System.out.println(arrayOfObjects[0]);
System.out.println(arrayOfStrings[2]);
System.out.println(arrayOfObjects.clone());
System.out.println(arrayOfStrings.toString());
Access, a[b]
31/171
Special Case
 Syntax and semantics built in the compiler
Pseudo-field
System.out.println(arrayOfObjects.length);
System.out.println(arrayOfStrings.length);
System.out.println(arrayOfObjects[0]);
System.out.println(arrayOfStrings[2]);
System.out.println(arrayOfObjects.clone());
System.out.println(arrayOfStrings.toString());
Access, a[b]
In the Java programming language
arrays are objects (§4.3.1), are
dynamically created, and may be
assigned to variables of type Object
(§4.3.2). All methods of class Object
may be invoked on an array.
—JLS
32/171
Outline
 History
 Problem
 Special Case
 General Definitions
 Generics Definitions
– Parametric
Polymorphism
– Other Bounded
Parametric
Polymorphisms
 When to Use Generics
 How to Use Generics
 Caveats with Generics
 Reflecting on Generics
 Conclusion
 Few References
33/171
General Definitions
 Polymorphism
– Ad-hoc polymorphism
– Subtype polymorphism
– Parametric polymorphism
• Implicit
• Explicit
34/171
General Definitions
 Ad-hoc polymorphism
– Method overloading
– Not a feature of the type system
– Dispatch mechanism
• Typically, dispatch depends on the concrete type of
the receiver of a method
Christopher Strachey ; “Fundamental Concepts in Programming Languages” ; Higher-Order and
Symbolic Computation, volume 13, issue 1-2, pp. 11-49, Springer, 2000.
35/171
General Definitions
 Ad-hoc polymorphism
– A name may have more than one meaning
• It may refer to more than one algorithm
– The choice of the algorithm is context-
dependent but know at compile-time
(Early binding when compared to the following
subtype polymorphism)
36/171
General Definitions
 Subtype polymorphism
– Liskov substitution principle
• Let q(x) be a property provable about objects x
of type T. Then q(y) should be true for objects y
of type S where S is a subtype of T
(Late binding when compared to the previous
ad hoc polymorphism)
Barbara Liskov
*1939
37/171
General Definitions
 Subtype polymorphism
package net.ptidej.generics.java;
import java.awt.Frame;
import java.lang.Long;
public class Example3 {
public static void main(final String[] args) {
Object o;
o = new Long(1);
System.out.println(o.toString());
o = new Frame();
System.out.println(o.toString());
}
}
38/171
General Definitions
 Subtype polymorphism
package net.ptidej.generics.java;
import java.awt.Frame;
import java.lang.Long;
public class Example3 {
public static void main(final String[] args) {
Object o;
o = new Long(1);
System.out.println(o.toString());
o = new Frame();
System.out.println(o.toString());
}
}
Declared type vs.
concrete types
39/171
General Definitions
 Parametric polymorphism
public class NonGenericBox {
private Object object;
public void set(final Object object) {
this.object = object;
}
public Object get() {
return this.object;
}
}
public void useOfNonGenericBox() {
final NonGenericBox aNonGenericBox = new NonGenericBox();
aNonGenericBox.set(new String());
final String myString = (String) aNonGenericBox.get();
System.out.println(myString);
}
40/171
General Definitions
 Parametric polymorphism
public class NonGenericBox {
private Object object;
public void set(final Object object) {
this.object = object;
}
public Object get() {
return this.object;
}
}
public void useOfNonGenericBox() {
final NonGenericBox aNonGenericBox = new NonGenericBox();
aNonGenericBox.set(new String());
final String myString = (String) aNonGenericBox.get();
System.out.println(myString);
}
Must cast to ask
compiler to allow
the assignment
41/171
General Definitions
 Parametric polymorphism
public class NonGenericBox {
private Object object;
public void set(final Object object) {
this.object = object;
}
public Object get() {
return this.object;
}
}
public void useOfNonGenericBox() {
final NonGenericBox aNonGenericBox = new NonGenericBox();
aNonGenericBox.set(new String());
final Integer myInteger = (Integer) aNonGenericBox.get();
System.out.println(myInteger);
}
42/171
General Definitions
 Parametric polymorphism
public class NonGenericBox {
private Object object;
public void set(final Object object) {
this.object = object;
}
public Object get() {
return this.object;
}
}
public void useOfNonGenericBox() {
final NonGenericBox aNonGenericBox = new NonGenericBox();
aNonGenericBox.set(new String());
final Integer myInteger = (Integer) aNonGenericBox.get();
System.out.println(myInteger);
}
Legal!
43/171
General Definitions
 Parametric polymorphism
We use Java vocabulary in the following
44/171
General Definitions
 Parametric polymorphism
Type parameter
We use Java vocabulary in the following
45/171
General Definitions
 Parametric polymorphism
Type parameter
We use Java vocabulary in the following
Type variable
46/171
General Definitions
 Parametric polymorphism
Type parameter
Generic type
declaration
We use Java vocabulary in the following
Type variable
47/171
General Definitions
 Parametric polymorphism
Type parameter
Generic type
declaration
We use Java vocabulary in the following
Parameterised
methods
Type variable
48/171
General Definitions
 Parametric polymorphism
Type parameter
Generic type
declaration
We use Java vocabulary in the following
Type argument
Parameterised
methods
Type variable
49/171
General Definitions
 Parametric polymorphism
public class GenericBox<T> {
private T t;
public void set(final T t) {
this.t = t;
}
public T get() {
return this.t;
}
}
public void useOfGenericBox() {
final GenericBox<String> aGenericBox = new GenericBox<String>();
aGenericBox.set(new String());
final String myString = aGenericBox.get();
System.out.println(myString);
}
50/171
General Definitions
 Parametric polymorphism
public class GenericBox<T> {
private T t;
public void set(final T t) {
this.t = t;
}
public T get() {
return this.t;
}
}
public void useOfGenericBox() {
final GenericBox<String> aGenericBox = new GenericBox<String>();
aGenericBox.set(new String());
final Integer myInteger = (Integer) aNonGenericBox.get();
System.out.println(myInteger);
}
51/171
General Definitions
 Parametric polymorphism
public class GenericBox<T> {
private T t;
public void set(final T t) {
this.t = t;
}
public T get() {
return this.t;
}
}
public void useOfGenericBox() {
final GenericBox<String> aGenericBox = new GenericBox<String>();
aGenericBox.set(new String());
final Integer myInteger = (Integer) aNonGenericBox.get();
System.out.println(myInteger);
}
Illegal!
52/171
General Definitions
 Parametric polymorphism
package net.ptidej.generics.java;
public class Example4 {
public static void main(final String[] args) {
System.out.println(Util.<String>compare("a", "b"));
System.out.println(Util.<String>compare(new String(""), new Long(1)));
System.out.println(Util.compare(new String(""), new Long(1)));
}
}
public class Util {
public static <T> boolean compare(T t1, T t2) {
return t1.equals(t2);
}
}
53/171
General Definitions
 Parametric polymorphism
package net.ptidej.generics.java;
public class Example4 {
public static void main(final String[] args) {
System.out.println(Util.<String>compare("a", "b"));
System.out.println(Util.<String>compare(new String(""), new Long(1)));
System.out.println(Util.compare(new String(""), new Long(1)));
}
}
public class Util {
public static <T> boolean compare(T t1, T t2) {
return t1.equals(t2);
}
}
Generic method
54/171
General Definitions
 Parametric polymorphism
package net.ptidej.generics.java;
public class Example4 {
public static void main(final String[] args) {
System.out.println(Util.<String>compare("a", "b"));
System.out.println(Util.<String>compare(new String(""), new Long(1)));
System.out.println(Util.compare(new String(""), new Long(1)));
}
}
public class Util {
public static <T> boolean compare(T t1, T t2) {
return t1.equals(t2);
}
}
Generic method
Explicit calls
55/171
General Definitions
 Parametric polymorphism
package net.ptidej.generics.java;
public class Example4 {
public static void main(final String[] args) {
System.out.println(Util.<String>compare("a", "b"));
System.out.println(Util.<String>compare(new String(""), new Long(1)));
System.out.println(Util.compare(new String(""), new Long(1)));
}
}
public class Util {
public static <T> boolean compare(T t1, T t2) {
return t1.equals(t2);
}
}
Generic method
Explicit calls
Implicit call
56/171
Outline
 History
 Problem
 Special Case
 General Definitions
 Generics Definitions
– Parametric
Polymorphism
– Other Bounded
Parametric
Polymorphisms
 When to Use Generics
 How to Use Generics
 Caveats with Generics
 Reflecting on Generics
 Conclusion
 Few References
57/171
Generics Definitions
“A generic type is a generic class or
interface that is parameterized over types.”
—The Java Tutorials, Oracle
58/171
Generics Definitions
 Java generics are one implementation of
parametric polymorphism
– Type erasure
 Type parameters can be constrained
– Lower bounds
– Upper bounds
to obtain bounded type parameters
59/171
Outline
 History
 Problem
 Special Case
 General Definitions
 Generics Definitions
– Parametric
Polymorphism
– Other Bounded
Parametric
Polymorphisms
 When to Use Generics
 How to Use Generics
 Caveats with Generics
 Reflecting on Generics
 Conclusion
 Few References
60/171
Generics Definitions
 Parametric polymorphism
– Predicative
• ML
– Impredicative
• System F
• C++, Java 1.5
– Bounded
• C++ in one way, Java 1.5 in another
Martín Abadi, Luca Cardelli, Pierre-Louis Curien ; “Formal Parametric Polymorphism” ; SRC
research report, issue 109, Digital, Systems Research Center, 1993.
61/171
Generics Definitions
 Predicative parametric polymorphism
– A type T containing a type variable  may not be
used in such a way that  is instantiated to a
polymorphic type
62/171
Generics Definitions
 Predicative parametric polymorphism
– A type T containing a type variable  may not be
used in such a way that  is instantiated to a
polymorphic type
final GenericBox<String> aGenericBox = new GenericBox<String>();
aGenericBox.set(new String());
final GenericBox<List<String>> aGenericBox = new GenericBox<List<String>>();
aGenericBox.set(new String());
63/171
Generics Definitions
 Predicative parametric polymorphism
– A type T containing a type variable  may not be
used in such a way that  is instantiated to a
polymorphic type
final GenericBox<String> aGenericBox = new GenericBox<String>();
aGenericBox.set(new String());
final GenericBox<List<String>> aGenericBox = new GenericBox<List<String>>();
aGenericBox.set(new String());
64/171
Generics Definitions
 Impredicative parametric polymorphism
– Example 1
– Example 2
65/171
Generics Definitions
 Impredicative parametric polymorphism
– Example 1
– Example 2
final GenericBox<List<String>> aGenericBox = new GenericBox<List<String>>();
aGenericBox.set(new String());
66/171
Generics Definitions
 Impredicative parametric polymorphism
– Example 1
– Example 2
import java.util.List;
public interface ISort<E extends Comparable<E>> {
public List<E> sort(final List<E> aList);
}
final GenericBox<List<String>> aGenericBox = new GenericBox<List<String>>();
aGenericBox.set(new String());
67/171
Generics Definitions
 Bounded parametric polymorphism
The type E of the list elements must implement
the interface Comparable
import java.util.List;
public interface ISort<E extends Comparable<E>> {
public List<E> sort(final List<E> aList);
}
68/171
Generics Definitions
 Bounded parametric polymorphism
“Bounded genericity is less about limiting the
types accepted by [a] generic class […] and
more about giving the generic class a more
complete information on its generic type T […] to
validate the call to its methods at compile time.”
—paercebal
http://stackoverflow.com/questions/6803100/achieving-bounded-genericity-in-c/6803124
69/171
Generics
Definitions
public class Example5 {
public static void main(final String[] args) {
final Sort<A> sort = new Sort<A>();
final List<A> listOfAs = new ArrayList<A>();
sort.sort(listOfAs);
System.out.println();
}
}
class Sort<E extends Comparable<E>> {
public List<E> sort(final List<E> aList) {
return // TO DO
}
}
class A implements Comparable<A> {
public int compareTo(final A o) {
return // TO DO
}
}
class B implements Comparable<B> {
public int compareTo(final B o) {
return // TO DO
}
}
70/171
Generics
Definitions
public class Example5 {
public static void main(final String[] args) {
final Sort<A> sort = new Sort<A>();
final List<A> listOfAs = new ArrayList<A>();
sort.sort(listOfAs);
System.out.println();
}
}
class Sort<E extends Comparable<E>> {
public List<E> sort(final List<E> aList) {
return // TO DO
}
}
class A implements Comparable<A> {
public int compareTo(final A o) {
return // TO DO
}
}
class B implements Comparable<B> {
public int compareTo(final B o) {
return // TO DO
}
}
Must be comparable (with itself)
71/171
Outline
 History
 Problem
 Special Case
 General Definitions
 Generics Definitions
– Parametric
Polymorphism
– Other Bounded
Parametric
Polymorphisms
 When to Use Generics
 How to Use Generics
 Caveats with Generics
 Reflecting on Generics
 Conclusion
 Few References
72/171
Generics Definitions
 Other bounded parametric polymorphisms
Java
C++
73/171
Generics Definitions
 Other bounded parametric polymorphisms
“This feature is provided as-is and where-used
by the compiler: in a way similar to duck typing,
but resolved at compile-time. [Compilation
succeeds] only if the generic type class
[declares] the [expected method].”
—paercebal
http://stackoverflow.com/questions/6803100/achieving-bounded-genericity-in-c/6803124
74/171
Generics
Definitions class X {
public:
virtual void kewl_method() { /* etc. */ }
};
class Y: public X {
public:
virtual void kewl_method() { /* etc. */ }
};
class Z {
public:
virtual void kewl_method() { /* etc. */ }
};
class K {
public:
virtual void wazaa() { /* etc. */ }
};
template<typename T>
class A {
public:
void foo() {
T t;
t.kewl_method();
}
};
75/171
Generics
Definitions class X {
public:
virtual void kewl_method() { /* etc. */ }
};
class Y: public X {
public:
virtual void kewl_method() { /* etc. */ }
};
class Z {
public:
virtual void kewl_method() { /* etc. */ }
};
class K {
public:
virtual void wazaa() { /* etc. */ }
};
template<typename T>
class A {
public:
void foo() {
T t;
t.kewl_method();
}
};
No common type
76/171
Generics
Definitions class X {
public:
virtual void kewl_method() { /* etc. */ }
};
class Y: public X {
public:
virtual void kewl_method() { /* etc. */ }
};
class Z {
public:
virtual void kewl_method() { /* etc. */ }
};
class K {
public:
virtual void wazaa() { /* etc. */ }
};
template<typename T>
class A {
public:
void foo() {
T t;
t.kewl_method();
}
};
Common API
77/171
Generics
Definitions
int main()
{
// A's constraint is : implements kewl_method
A<X> x ; x.foo() ;
// OK: x implements kewl_method
A<Y> y ; y.foo() ;
// OK: y derives from X
A<Z> z ; z.foo() ;
// OK: z implements kewl_method
A<K> k ; k.foo() ;
// NOT OK : K won't compile: /main.cpp error:
// ‘class K’ has no member named ‘kewl_method’
return 0;
}
78/171
Generics
Definitions
“Static” duct typing
int main()
{
// A's constraint is : implements kewl_method
A<X> x ; x.foo() ;
// OK: x implements kewl_method
A<Y> y ; y.foo() ;
// OK: y derives from X
A<Z> z ; z.foo() ;
// OK: z implements kewl_method
A<K> k ; k.foo() ;
// NOT OK : K won't compile: /main.cpp error:
// ‘class K’ has no member named ‘kewl_method’
return 0;
}
79/171
Generics Definitions
 Duck typing
– Dynamically-typed languages: Smalltalk
– Statically-typed language: C++
“When I see a bird that walks like a duck and
swims like a duck and quacks like a duck, I call
that bird a duck.”
—Alex Martelli or James W. Riley
80/171
Generics Definitions
 Dynamically-typed languages: Smalltalk
Object subclass: #D
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'CSE3009'.
D compile: 'needAFooMethod: anObjectWithaFooMethod
"Example of duck typing"
anObjectWithaFooMethod foo.'.
81/171
Generics Definitions
 Dynamically-typed languages: Smalltalk
Object subclass: #D
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'CSE3009'.
D compile: 'needAFooMethod: anObjectWithaFooMethod
"Example of duck typing"
anObjectWithaFooMethod foo.'.
Any object with a
foo method will do
82/171
Generics Definitions
 Dynamically-typed languages: Smalltalk
SMUtilities subclass: #D1
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'CSE3009'.
D1 compile: 'foo
Transcript show: ''D1'' ; cr.'.
PointArray variableWordSubclass: #D2
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'CSE3009'.
D2 compile: 'foo
Transcript show: ''D2'' ; cr.'.
83/171
Generics Definitions
 Dynamically-typed languages: Smalltalk
SMUtilities subclass: #D1
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'CSE3009'.
D1 compile: 'foo
Transcript show: ''D1'' ; cr.'.
PointArray variableWordSubclass: #D2
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'CSE3009'.
D2 compile: 'foo
Transcript show: ''D2'' ; cr.'.
Two unrelated
classes
84/171
Generics Definitions
 Dynamically-typed languages: Smalltalk
d := D new.
d needAFooMethod: (D1 new).
d needAFooMethod: (D2 new).
D1
D2
85/171
Outline
 History
 Problem
 Special Case
 General Definitions
 Generics Definitions
– Parametric
Polymorphism
– Other Bounded
Parametric
Polymorphisms
 When to Use Generics
 How to Use Generics
 Caveats with Generics
 Reflecting on Generics
 Conclusion
 Few References
86/171
When to Use Generics
 Scenario 1: you want to enforce type safety
for containers and remove the need for
typecasts when using these containers
public final class Example1 {
public static void main(final String[] args) {
final List untypedList = new ArrayList();
untypedList.add(new String());
final Integer i = (Integer) untypedList.get(0);
final List<String> typedList = new ArrayList<String>();
typedList.add(new String());
final Integer i = (Integer) typedList.get(0);
}
}
Does not compile
87/171
When to Use Generics
 Scenario 2: you want to build generic
algorithms that work on several types of
(possible unrelated) things
import java.util.List;
public interface ISort<E extends Comparable<E>> {
public List<E> sort(final List<E> aList);
}
88/171
Outline
 History
 Problem
 Special Case
 General Definitions
 Generics Definitions
– Parametric
Polymorphism
– Other Bounded
Parametric
Polymorphisms
 When to Use Generics
 How to Use Generics
 Caveats with Generics
 Reflecting on Generics
 Conclusion
 Few References
89/171
How to Use Generics
 Lots of resources
 Lots of discussions
 First step http://docs.oracle.com/javase/
tutorial/java/generics/index.html
 Then, http://stackoverflow.com/search?
q=%22java+generics%22
– 1,323 results as of 2013/04/14
90/171
How to Use Generics
 Typed containers, before
import java.util.ArrayList;
import java.util.List;
public final class Example1Before {
public static void main(final String[] args) {
final List untypedList = new ArrayList();
untypedList.add(new String());
final Integer i = (Integer) untypedList.get(0);
}
}
91/171
How to Use Generics
 Typed containers, what happens?
import java.util.ArrayList;
import java.util.List;
public final class Example1Before {
public static void main(final String[] args) {
final List untypedList = new ArrayList();
untypedList.add(new String());
final Integer i = (Integer) untypedList.get(0);
}
}
92/171
How to Use Generics
 Typed containers, what happens?
import java.util.ArrayList;
import java.util.List;
public final class Example1Before {
public static void main(final String[] args) {
final List untypedList = new ArrayList();
untypedList.add(new String());
final Integer i = (Integer) untypedList.get(0);
}
}
Exception in thread "main" java.lang.ClassCastException:
java.lang.String cannot be cast to java.lang.Integer
at net.ptidej.generics.java.Example1Before.main(Example1Before.java:29)
93/171
How to Use Generics
 Typed containers, another look
import java.util.ArrayList;
import java.util.List;
public final class Example1Before {
public static void main(final String[] args) {
final List untypedList = new ArrayList();
untypedList.add(new String());
final Integer i = (Integer) untypedList.get(0);
}
}
94/171
How to Use Generics
 Typed containers, another look
import java.util.ArrayList;
import java.util.List;
public final class Example1Before {
public static void main(final String[] args) {
final List untypedList = new ArrayList();
untypedList.add(new String());
final Integer i = (Integer) untypedList.get(0);
}
}
List and ArrayList
are raw types, compiler
cannot typecheck
95/171
How to Use Generics
 Typed containers, solution
import java.util.ArrayList;
import java.util.List;
public final class Example1Before {
public static void main(final String[] args) {
final List<String> typedList = new ArrayList<String>();
typedList.add(new String());
final Integer i = (Integer) typedList.get(0);
}
}
96/171
How to Use Generics
 Typed containers, solution
import java.util.ArrayList;
import java.util.List;
public final class Example1Before {
public static void main(final String[] args) {
final List<String> typedList = new ArrayList<String>();
typedList.add(new String());
final Integer i = (Integer) typedList.get(0);
}
}
Does not compile because String
and Interger are not compatible
97/171
How to Use Generics
 Family of algorithms, before
public interface Enumeration {
/**
* Tests if this enumeration contains more elements.
*
* @return <code>true</code> if and only if this enumeration object
* contains at least one more element to provide;
* <code>false</code> otherwise.
*/
boolean hasMoreElements();
/**
* Returns the next element of this enumeration if this enumeration
* object has at least one more element to provide.
*
* @return the next element of this enumeration.
* @exception NoSuchElementException if no more elements exist.
*/
Object nextElement();
}
98/171
How to Use Generics
 Family of algorithms, what happens?
public interface Enumeration {
/**
* Tests if this enumeration contains more elements.
*
* @return <code>true</code> if and only if this enumeration object
* contains at least one more element to provide;
* <code>false</code> otherwise.
*/
boolean hasMoreElements();
/**
* Returns the next element of this enumeration if this enumeration
* object has at least one more element to provide.
*
* @return the next element of this enumeration.
* @exception NoSuchElementException if no more elements exist.
*/
Object nextElement();
}
99/171
How to Use Generics
 Family of algorithms, what happens?
public interface Enumeration {
/**
* Tests if this enumeration contains more elements.
*
* @return <code>true</code> if and only if this enumeration object
* contains at least one more element to provide;
* <code>false</code> otherwise.
*/
boolean hasMoreElements();
/**
* Returns the next element of this enumeration if this enumeration
* object has at least one more element to provide.
*
* @return the next element of this enumeration.
* @exception NoSuchElementException if no more elements exist.
*/
Object nextElement();
}
Forces clients
to use Object
100/171
How to Use Generics
 Family of algorithms, another look
public interface Enumeration {
/**
* Tests if this enumeration contains more elements.
*
* @return <code>true</code> if and only if this enumeration object
* contains at least one more element to provide;
* <code>false</code> otherwise.
*/
boolean hasMoreElements();
/**
* Returns the next element of this enumeration if this enumeration
* object has at least one more element to provide.
*
* @return the next element of this enumeration.
* @exception NoSuchElementException if no more elements exist.
*/
Object nextElement();
}
101/171
How to Use Generics
 Family of algorithms, another look
public interface Enumeration {
/**
* Tests if this enumeration contains more elements.
*
* @return <code>true</code> if and only if this enumeration object
* contains at least one more element to provide;
* <code>false</code> otherwise.
*/
boolean hasMoreElements();
/**
* Returns the next element of this enumeration if this enumeration
* object has at least one more element to provide.
*
* @return the next element of this enumeration.
* @exception NoSuchElementException if no more elements exist.
*/
Object nextElement();
}
Clients must know the
type of the next element
102/171
How to Use Generics
 Family of algorithms, solution
public interface Enumeration<E> {
/**
* Tests if this enumeration contains more elements.
*
* @return <code>true</code> if and only if this enumeration object
* contains at least one more element to provide;
* <code>false</code> otherwise.
*/
boolean hasMoreElements();
/**
* Returns the next element of this enumeration if this enumeration
* object has at least one more element to provide.
*
* @return the next element of this enumeration.
* @exception NoSuchElementException if no more elements exist.
*/
E nextElement();
}
103/171
How to Use Generics
 Family of algorithms, solution
public interface Enumeration<E> {
/**
* Tests if this enumeration contains more elements.
*
* @return <code>true</code> if and only if this enumeration object
* contains at least one more element to provide;
* <code>false</code> otherwise.
*/
boolean hasMoreElements();
/**
* Returns the next element of this enumeration if this enumeration
* object has at least one more element to provide.
*
* @return the next element of this enumeration.
* @exception NoSuchElementException if no more elements exist.
*/
E nextElement();
}
104/171
How to Use Generics
 Family of algorithms, solution
public interface Enumeration<E> {
/**
* Tests if this enumeration contains more elements.
*
* @return <code>true</code> if and only if this enumeration object
* contains at least one more element to provide;
* <code>false</code> otherwise.
*/
boolean hasMoreElements();
/**
* Returns the next element of this enumeration if this enumeration
* object has at least one more element to provide.
*
* @return the next element of this enumeration.
* @exception NoSuchElementException if no more elements exist.
*/
E nextElement();
}
Clients can specify the
type of the next element
105/171
Outline
 History
 Problem
 Special Case
 General Definitions
 Generics Definitions
– Parametric
Polymorphism
– Other Bounded
Parametric
Polymorphisms
 When to Use Generics
 How to Use Generics
 Caveats with Generics
 Reflecting on Generics
 Conclusion
 Few References
106/171
Caveats with Generics
 ints and Integers, before
public interface List extends Collection {
...
boolean add(Object o);
boolean remove(Object o);
Object remove(int index);
...
}
107/171
Caveats with Generics
 ints and Integers, now
public interface List<E> extends Collection<E> {
...
boolean add(E e);
boolean remove(Object o);
E remove(int index);
...
}
108/171
Caveats with Generics
 ints and Integers, now
public interface List<E> extends Collection<E> {
...
boolean add(E e);
boolean remove(Object o);
E remove(int index);
...
}
109/171
Caveats with Generics
 ints and Integers, what happens?
import java.util.ArrayList;
import java.util.List;
public class Autoboxing {
public static void main(String[] args) {
final List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(new Integer(2));
list.remove(1);
list.remove(new Integer(1));
System.out.println(list.size());
}
}
110/171
Caveats with Generics
 ints and Integers, what happens?
import java.util.ArrayList;
import java.util.List;
public class Autoboxing {
public static void main(String[] args) {
final List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(new Integer(2));
list.remove(1);
list.remove(new Integer(1));
System.out.println(list.size());
}
}
Autoboxing from
int to Integer
111/171
Caveats with Generics
 ints and Integers, what happens?
import java.util.ArrayList;
import java.util.List;
public class Autoboxing {
public static void main(String[] args) {
final List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(new Integer(2));
list.remove(1);
list.remove(new Integer(1));
System.out.println(list.size());
}
}
Autoboxing from
int to Integer
Exact parameter
matching takes
over autoboxing
112/171
Caveats with Generics
 ints and Integers, what happens?
import java.util.ArrayList;
import java.util.List;
public class Autoboxing {
public static void main(String[] args) {
final List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(new Integer(2));
list.remove(1);
list.remove(new Integer(1));
System.out.println(list.size());
}
}
Autoboxing from
int to Integer
Exact parameter
matching takes
over autoboxing
0
113/171
Caveats with Generics
 Use of clone(), before
http://stackoverflow.com/questions/3941850/
java-how-to-use-clone-and-what-about-the-cast-check
import java.util.ArrayList;
public class CloningBefore {
public static void main(final String[] args) {
final ArrayList list1 = new ArrayList();
list1.add(new Integer(1));
list1.add(new Integer(2));
final ArrayList list2 = (ArrayList) list1.clone();
System.out.println(list2);
}
}
114/171
Caveats with Generics
 Use of clone(), before
http://stackoverflow.com/questions/3941850/
java-how-to-use-clone-and-what-about-the-cast-check
import java.util.ArrayList;
public class CloningBefore {
public static void main(final String[] args) {
final ArrayList list1 = new ArrayList();
list1.add(new Integer(1));
list1.add(new Integer(2));
final ArrayList list2 = (ArrayList) list1.clone();
System.out.println(list2);
}
}
No complains
for the compiler
115/171
Caveats with Generics
 Use of clone(), now
import java.util.ArrayList;
public class CloningNow {
public static void main(final String[] args) {
final ArrayList<Integer> list1 = new ArrayList<Integer>();
list1.add(1);
list1.add(new Integer(2));
final ArrayList<Integer> list2 = (ArrayList<Integer>) list1.clone();
System.out.println(list2);
}
}
116/171
Caveats with Generics
 Use of clone(), now
import java.util.ArrayList;
public class CloningNow {
public static void main(final String[] args) {
final ArrayList<Integer> list1 = new ArrayList<Integer>();
list1.add(1);
list1.add(new Integer(2));
final ArrayList<Integer> list2 = (ArrayList<Integer>) list1.clone();
System.out.println(list2);
}
}
117/171
Caveats with Generics
 Use of clone(), now
import java.util.ArrayList;
public class CloningNow {
public static void main(final String[] args) {
final ArrayList<Integer> list1 = new ArrayList<Integer>();
list1.add(1);
list1.add(new Integer(2));
final ArrayList<Integer> list2 = (ArrayList<Integer>) list1.clone();
System.out.println(list2);
}
}
Type safety: Unchecked cast from
Object to ArrayList<Integer>
118/171
Caveats with Generics
 Use of clone(), what happens?
– Compiler is now “stricter”
– Compiler warns of a type-unsafe operation
119/171
Caveats with Generics
 Use of clone(), solution
– Use copy-constructor
to obtain type-safety and remove any warning
import java.util.ArrayList;
public class CloningSolution {
public static void main(final String[] args) {
final ArrayList<Integer> list1 = new ArrayList<Integer>();
list1.add(1);
list1.add(new Integer(2));
final ArrayList<Integer> list2 = new ArrayList<Integer>(list1);
System.out.println(list2);
}
}
120/171
Caveats with Generics
 Use of clone(), solution
– Use copy-constructor
to obtain type-safety and remove any warning
import java.util.ArrayList;
public class CloningSolution {
public static void main(final String[] args) {
final ArrayList<Integer> list1 = new ArrayList<Integer>();
list1.add(1);
list1.add(new Integer(2));
final ArrayList<Integer> list2 = new ArrayList<Integer>(list1);
System.out.println(list2);
}
}
121/171
Caveats with Generics
 Use of clone(), solution
– Suppress warning
public class CloningSolutionWarning {
public static void main(final String[] args) {
final ArrayList<Integer> list1 = new ArrayList<Integer>();
list1.add(1);
list1.add(new Integer(2));
@SuppressWarnings("unchecked")
final ArrayList<Integer> list2 = (ArrayList<Integer>) list1.clone();
System.out.println(list2);
}
}
122/171
Caveats with Generics
 Use of clone(), solution
– Suppress warning
… not really a solution!
public class CloningSolutionWarning {
public static void main(final String[] args) {
final ArrayList<Integer> list1 = new ArrayList<Integer>();
list1.add(1);
list1.add(new Integer(2));
@SuppressWarnings("unchecked")
final ArrayList<Integer> list2 = (ArrayList<Integer>) list1.clone();
System.out.println(list2);
}
}
123/171
Caveats with Generics
 Instantiating a type variable, problem
public class InstantiatingTypeParameterProblem<T> {
public static void main(final String[] args) {
...
}
public T getInstanceOfT (){
// Neither lines work:
return new T();
return T.newInstance();
}
...
}
124/171
Caveats with Generics
 Instantiating a type variable, problem
public class InstantiatingTypeParameterProblem<T> {
public static void main(final String[] args) {
...
}
public T getInstanceOfT (){
// Neither lines work:
return new T();
return T.newInstance();
}
...
}
Cannot instantiate
the type T
125/171
Caveats with Generics
 Instantiating a type variable, problem
public class InstantiatingTypeParameterProblem<T> {
public static void main(final String[] args) {
...
}
public T getInstanceOfT (){
// Neither lines work:
return new T();
return T.newInstance();
}
...
}
Cannot instantiate
the type T
The method newInstance()
is undefined for the type T
126/171
Caveats with Generics
 Instantiating a type variable, what happens?
The type parameter T is erased at compile-time,
the JVM cannot use it at run-time
public class InstantiatingTypeParameterProblem<T> {
public static void main(final String[] args) {
...
}
public T getInstanceOfT (){
// Neither lines work:
return new T();
return T.newInstance();
}
...
}
127/171
Caveats with Generics
 Instantiating a type variable, solution #1
– Pass the class of T as parameter
public class InstantiatingTypeParameterSolution1<T> {
public static void main(final String[] args) {
...
}
public T getInstanceOfT(final Class<T> classOfT) {
return classOfT.newInstance();
}
...
}
128/171
Caveats with Generics
 Instantiating a type variable, solution #2
– Pass a factory of T as parameter
interface Factory<T> {
T getInstance();
}
class Something {
public static class FactoryOfSomething implements Factory<Something> {
public Something getInstance() {
return new Something();
}
}
}
public class InstantiatingTypeParameterSolution2<T> {
public static void main(final String[] args) {
...
}
public T getInstanceOfT(final Factory<T> factory) {
return factory.getInstance();
}
...
}
129/171
Caveats with Generics
 Instantiating a type variable, solution #3
– Prevent type erasure by specialising an
interesting class
public class InstantiatingTypeParameterSolution3 extends GenericClass<String> {
public static void main(final String[] args) {
final InstantiatingTypeParameterSolution3 i =
new InstantiatingTypeParameterSolution3();
i.foo();
}
public void foo() {
final Object s = this.getInstanceOfT();
System.out.println(s.getClass());
}
}
130/171
Caveats with Generics
 Instantiating a type variable, solution #3
– Prevent type erasure by specialising an
interesting class
public class InstantiatingTypeParameterSolution3 extends GenericClass<String> {
public static void main(final String[] args) {
final InstantiatingTypeParameterSolution3 i =
new InstantiatingTypeParameterSolution3();
i.foo();
}
public void foo() {
final Object s = this.getInstanceOfT();
System.out.println(s.getClass());
}
}
Type argument
and subclassing
131/171
Caveats with Generics
 Instantiating a type variable, solution #3
– Prevent type erasure by specialising an
interesting class
import java.lang.reflect.ParameterizedType;
abstract class GenericClass<T> {
public T getInstanceOfT() {
final ParameterizedType pt =
(ParameterizedType) this.getClass().getGenericSuperclass();
final String parameterClassName =
pt.getActualTypeArguments()[0].toString().split("s")[1];
T parameter = (T) Class.forName(parameterClassName).newInstance();
return parameter;
}
}
132/171
Caveats with Generics
 Instantiating a type variable, solution #3
– Prevent type erasure by specialising an
interesting class
import java.lang.reflect.ParameterizedType;
abstract class GenericClass<T> {
public T getInstanceOfT() {
final ParameterizedType pt =
(ParameterizedType) this.getClass().getGenericSuperclass();
final String parameterClassName =
pt.getActualTypeArguments()[0].toString().split("s")[1];
T parameter = (T) Class.forName(parameterClassName).newInstance();
return parameter;
}
}
The superclass is generic,
the subclass specialises it
133/171
Caveats with Generics
 Implicit generic methods
– As with explicit generic methods, use Object in
the generated bytecodes
public final class Example4 {
public static void main(final String[] args) {
System.out.println(Util4.<String> compare("a", "b"));
// The following line, as expected, produces a type mismatch error
// System.out.println(Util.<String> compare(new String(""), new Long(1)));
System.out.println(Util4.compare(new String(""), new Long(1)));
}
}
final class Util4 {
public static <T> boolean compare(final T t1, final T t2) {
return t1.equals(t2);
}
}
134/171
Caveats with Generics
 Implicit generic methods
– As with explicit generic methods, use Object in
the generated bytecodes
to ensure backward-compatibility with
non-generic Java code
// Method descriptor #15 ([Ljava/lang/String;)V
// Stack: 7, Locals: 1
public static void main(java.lang.String[] args);
…
14 invokevirtual net.ptidej.generics.java.Util44.compare(java.lang.Object, java.lang.Object) : boolean [29]
…
47 invokevirtual net.ptidej.generics.java.Util44.compare(java.lang.Object, java.lang.Object) : boolean [29]
…
135/171
Caveats with Generics
 Multiple bounds
“A type variable with multiple bounds is a
subtype of all the types listed in the bound.
If one of the bounds is a class, it must be
specified first.”
—The Java Tutorials, Oracle
136/171
Caveats with Generics
 Multiple bounds
class Example8A {
}
interface Example8B {
}
interface Example8C {
}
class Example8D<T extends Example8A & Example8B & Example8C> {
}
class Example8Test1 extends Example8A implements Example8B, Example8C {
}
class Example8Test2 extends Example8A {
}
public class Example8 {
public static void main(final String[] args) {
final Example8D<Example8Test1> d1 = new Example8D<Example8Test1>();
final Example8D<Example8Test2> d2 = new Example8D<Example8Test2>();
}
}
137/171
Caveats with Generics
 Multiple bounds
class Example8A {
}
interface Example8B {
}
interface Example8C {
}
class Example8D<T extends Example8A & Example8B & Example8C> {
}
class Example8Test1 extends Example8A implements Example8B, Example8C {
}
class Example8Test2 extends Example8A {
}
public class Example8 {
public static void main(final String[] args) {
final Example8D<Example8Test1> d1 = new Example8D<Example8Test1>();
final Example8D<Example8Test2> d2 = new Example8D<Example8Test2>();
}
}
Bound mismatch: The type Test2 is
not a valid substitute for the bounded
parameter <T extends …>
138/171
Caveats with Generics
 Upper- and lower-bounded wildcards
– Type parameters can be constrained to be
• Any subtype of a type, extends
• Any supertype of a type, super
– Useful with collections of items
import java.util.List;
public interface ISort<E extends Comparable<E>> {
public List<E> sort(final List<E> aList);
}
139/171
Caveats with Generics
 PECS
– Collections that produce extends
– Collections that consume super
Always from the point of view of the collection
http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs
140/171
Caveats with Generics
 PECS
– Collections that produce extends
• They produce elements of some types
• These types must be “topped” to tell the client that it
can safely expect to receive Somthing
• Any item from the collection is a Somthing (in the
sense of Liskov’s substitution)
Collection<? extends Something>
141/171
Caveats with Generics
 PECS
– Collections that consume super
• They consume elements of some types
• These types must be “bottomed” to tell the client that
it can safely put Something
• Any item in the collection is “at most” Something (in
the sense of Liskov’s substitution)
Collection<? super Something>
142/171
Caveats with Generics
 PECS
Another way to remember the producer /
consumer distinction is to think of a method
signature. If you have a method
useList(List), you are consuming the List
and so need covariance / extends. If your
method is List buildList(), then you are
producing the List and will need
contravariance / super
—Adapted from Raman
http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs
143/171
Caveats with Generics
 PECS
– Collections that produce and consume must just
use one type parameter
• Not legal to combine extends and super
Collection<Something>
144/171
Caveats with Generics
 Ambiguity between parameterised types
http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs
public class Example9 {
public static String f(List<String> list) {
System.out.println("strings");
return null;
}
public static Integer f(List<Integer> list) {
System.out.println("numbers");
return null;
}
public static void main(String[] args) {
f(Arrays.asList("asdf"));
f(Arrays.asList(123));
}
}
145/171
Caveats with Generics
 Ambiguity between parameterised types
http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs
public class Example9 {
public static String f(List<String> list) {
System.out.println("strings");
return null;
}
public static Integer f(List<Integer> list) {
System.out.println("numbers");
return null;
}
public static void main(String[] args) {
f(Arrays.asList("asdf"));
f(Arrays.asList(123));
}
}
Legality depends on compiler
• Eclipse 3.5 says yes
• Eclipse 3.6 says no
• Intellij 9 says yes
• Sun javac 1.6.0_20 says yes
• GCJ 4.4.3 says yes
• GWT compiler says yes
• Crowd says no
146/171
Outline
 History
 Problem
 Special Case
 General Definitions
 Generics Definitions
– Parametric
Polymorphism
– Other Bounded
Parametric
Polymorphisms
 When to Use Generics
 How to Use Generics
 Caveats with Generics
 Reflecting on Generics
 Conclusion
 Few References
147/171
Reflecting on Generics
 Java generics use type erasure
– (Most) Type parameters / arguments are erased
at compile-time and exist at run-time only as
annotations
– Ensure backward-compatibility with pre-generic
Java code
– Limit access to type parameters / arguments
using reflection
148/171
Caveats with Generics
 Type-safe use of getClass()
http://stackoverflow.com/questions/11060491/
is-there-a-clean-way-to-assign-the-class-of-a-generic-type-to-a-variable
class Example11A {
}
public class Example11 {
public static void main(final String[] args) {
final Example11A anA1 = new Example11A();
final Class<Example11A> anA1Class =
(Class<Example11A>) anA1.getClass();
System.out.println(anA1Class);
final Example11A anA2 = new Example11A();
final Class<? extends Example11A> anA2Class = anA2.getClass();
System.out.println(anA2Class);
}
}
149/171
Caveats with Generics
 Type-safe use of getClass()
http://stackoverflow.com/questions/11060491/
is-there-a-clean-way-to-assign-the-class-of-a-generic-type-to-a-variable
class Example11A {
}
public class Example11 {
public static void main(final String[] args) {
final Example11A anA1 = new Example11A();
final Class<Example11A> anA1Class =
(Class<Example11A>) anA1.getClass();
System.out.println(anA1Class);
final Example11A anA2 = new Example11A();
final Class<? extends Example11A> anA2Class = anA2.getClass();
System.out.println(anA2Class);
}
}
Type safety: Unchecked cast from
Class<capture#1-of ?
extends Example11A> to
Class<Example11A>
150/171
Caveats with Generics
 Type-safe use of getClass()
http://stackoverflow.com/questions/11060491/
is-there-a-clean-way-to-assign-the-class-of-a-generic-type-to-a-variable
class Example11A {
}
public class Example11 {
public static void main(final String[] args) {
final Example11A anA1 = new Example11A();
final Class<Example11A> anA1Class =
(Class<Example11A>) anA1.getClass();
System.out.println(anA1Class);
final Example11A anA2 = new Example11A();
final Class<? extends Example11A> anA2Class = anA2.getClass();
System.out.println(anA2Class);
}
}
Type safety: Unchecked cast from
Class<capture#1-of ?
extends Example11A> to
Class<Example11A>
No warning
151/171
Caveats with Generics
 Type-safe use of getClass()
class MyList extends ArrayList<Integer> {
}
public class Example11 {
public static void main(final String[] args) {
final List<Integer> list1 = new ArrayList<Integer>();
final Class<List<Integer>> list1Class =
(Class<List<Integer>>) list1.getClass();
System.out.println(list1Class);
final MyList list2 = new MyList();
Class<? extends List<? extends Integer>> list2Class = list2.getClass();
System.out.println(list2Class);
}
}
http://stackoverflow.com/questions/11060491/
is-there-a-clean-way-to-assign-the-class-of-a-generic-type-to-a-variable
152/171
Caveats with Generics
 Type-safe use of getClass()
class MyList extends ArrayList<Integer> {
}
public class Example11 {
public static void main(final String[] args) {
final List<Integer> list1 = new ArrayList<Integer>();
final Class<List<Integer>> list1Class =
(Class<List<Integer>>) list1.getClass();
System.out.println(list1Class);
final MyList list2 = new MyList();
Class<? extends List<? extends Integer>> list2Class = list2.getClass();
System.out.println(list2Class);
}
}
Type safety: Unchecked cast from
Class<capture#4-of ? extends
List> to Class<List<Integer>>
http://stackoverflow.com/questions/11060491/
is-there-a-clean-way-to-assign-the-class-of-a-generic-type-to-a-variable
153/171
Caveats with Generics
 Type-safe use of getClass()
class MyList extends ArrayList<Integer> {
}
public class Example11 {
public static void main(final String[] args) {
final List<Integer> list1 = new ArrayList<Integer>();
final Class<List<Integer>> list1Class =
(Class<List<Integer>>) list1.getClass();
System.out.println(list1Class);
final MyList list2 = new MyList();
Class<? extends List<? extends Integer>> list2Class = list2.getClass();
System.out.println(list2Class);
}
}
Type safety: Unchecked cast from
Class<capture#4-of ? extends
List> to Class<List<Integer>>
No warning
http://stackoverflow.com/questions/11060491/
is-there-a-clean-way-to-assign-the-class-of-a-generic-type-to-a-variable
154/171
Caveats with Generics
 Use of newInstance()
http://stackoverflow.com/questions/2592642/type-safety-unchecked-cast-from-object
class Example10A {
}
public class Example10 {
public static void main(final String[] args) {
final Class<Example10A> clazz1 = Example10A.class;
final Example10A anA1 = clazz1.newInstance();
System.out.println(anA1);
final Class<?> clazz2 = Class.forName(
"net.ptidej.generics.java.Example9A");
final Example10A anA2 = (Example10A) clazz2.newInstance();
System.out.println(anA2);
}
}
155/171
Caveats with Generics
 Obtaining the type of a type parameter
– Due to type erasure
• Type parameters are kept as annotations
• Type arguments disappear
Except for anonymous/local classes!
http://stackoverflow.com/questions/1901164/
get-type-of-a-generic-parameter-in-java-with-reflection
156/171
Caveats with Generics
 Obtaining the type of a type parameter
public final class Voodoo0 extends TestCase {
public static void chill(final List<?> aListWithSomeType) {
CommonTest.assertNotEqualAsExpected(
aListWithSomeType,
SpiderManVoodoo0.class);
}
public static void main(String... args) {
Voodoo0.chill(new ArrayList<SpiderManVoodoo0>());
}
public void test() {
Voodoo0.main(new String[0]);
}
}
class SpiderManVoodoo0 {
}
157/171
Caveats with Generics
 Obtaining the type of a type parameter
public final class Voodoo0 extends TestCase {
public static void chill(final List<?> aListWithSomeType) {
CommonTest.assertNotEqualAsExpected(
aListWithSomeType,
SpiderManVoodoo0.class);
}
public static void main(String... args) {
Voodoo0.chill(new ArrayList<SpiderManVoodoo0>());
}
public void test() {
Voodoo0.main(new String[0]);
}
}
class SpiderManVoodoo0 {
}
158/171
Caveats with Generics
 Obtaining the type of a type parameter
public static void main(java.lang.String...);
flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS
Code:
stack=2, locals=1, args_size=1
0: new #32 // class java/util/ArrayList
3: dup
4: invokespecial #34 // Method java/util/ArrayList."<init>":()V
7: invokestatic #35 // Method chill:(Ljava/util/List;)V
10: return
LineNumberTable:
line 38: 0
line 39: 10
LocalVariableTable:
Start Length Slot Name Signature
0 11 0 args [Ljava/lang/String;
159/171
Caveats with Generics
 Obtaining the type of a type parameter
public final class Voodoo1 extends TestCase {
public static void chill(final List<?> aListWithSomeType) {
CommonTest.assertNotEqualAsExpected(
aListWithSomeType,
SpiderManVoodoo1.class);
}
public static void main(String... args) {
Voodoo1.chill(new ArrayList<SpiderManVoodoo1>() {});
}
public void test() {
Voodoo1.main(new String[0]);
}
}
class SpiderManVoodoo1 {
}
160/171
Caveats with Generics
 Obtaining the type of a type parameter
public final class Voodoo1 extends TestCase {
public static void chill(final List<?> aListWithSomeType) {
CommonTest.assertNotEqualAsExpected(
aListWithSomeType,
SpiderManVoodoo1.class);
}
public static void main(String... args) {
Voodoo1.chill(new ArrayList<SpiderManVoodoo1>() {});
}
public void test() {
Voodoo1.main(new String[0]);
}
}
class SpiderManVoodoo1 {
}
161/171
Caveats with Generics
 Obtaining the type of a type parameter
public final class Voodoo1 extends TestCase {
public static void chill(final List<?> aListWithSomeType) {
CommonTest.assertNotEqualAsExpected(
aListWithSomeType,
SpiderManVoodoo1.class);
}
public static void main(String... args) {
Voodoo1.chill(new ArrayList<SpiderManVoodoo1>() {});
}
public void test() {
Voodoo1.main(new String[0]);
}
}
class SpiderManVoodoo1 {
}
162/171
Caveats with Generics
 Obtaining the type of a type parameter
public final class Voodoo1 extends TestCase {
public static void chill(final List<?> aListWithSomeType) {
CommonTest.assertNotEqualAsExpected(
aListWithSomeType,
SpiderManVoodoo1.class);
}
public static void main(String... args) {
Voodoo1.chill(new ArrayList<SpiderManVoodoo1>() {});
}
public void test() {
Voodoo1.main(new String[0]);
}
}
class SpiderManVoodoo1 {
}
Anonymous/local class
stores types information
163/171
Caveats with Generics
 Obtaining the type of a type parameter
public static void main(java.lang.String...);
flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS
Code:
stack=2, locals=1, args_size=1
0: new #32 // class net/ptidej/generics/java/erasure/Voodoo1$1
3: dup
4: invokespecial #34 // Method net/ptidej/generics/java/erasure/Voodoo1$1."<init>":()V
7: invokestatic #35 // Method chill:(Ljava/util/List;)V
10: return
LineNumberTable:
line 38: 0
line 41: 10
LocalVariableTable:
Start Length Slot Name Signature
0 11 0 args [Ljava/lang/String;
164/171
Caveats with Generics
 Obtaining the type of a type parameter
public static void main(java.lang.String...);
flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS
Code:
stack=2, locals=1, args_size=1
0: new #32 // class net/ptidej/generics/java/erasure/Voodoo1$1
3: dup
4: invokespecial #34 // Method net/ptidej/generics/java/erasure/Voodoo1$1."<init>":()V
7: invokestatic #35 // Method chill:(Ljava/util/List;)V
10: return
LineNumberTable:
line 38: 0
line 41: 10
LocalVariableTable:
Start Length Slot Name Signature
0 11 0 args [Ljava/lang/String;
165/171
Caveats with Generics
 Obtaining the type of a type parameter
// Compiled from Voodoo1.java (version 1.7 : 51.0, super bit)
// Signature: Ljava/util/ArrayList<Lca/polymtl/ptidej/generics/java/erasure/SpiderManVoodoo1;>;
class net.ptidej.generics.java.erasure.Voodoo1$1 extends java.util.ArrayList {
...
// Method descriptor #11 ()V
// Stack: 1, Locals: 1
Voodoo1$1();
0 aload_0 [this]
1 invokespecial java.util.ArrayList() [13]
4 return
Line numbers:
[pc: 0, line: 38]
[pc: 4, line: 1]
Local variable table:
[pc: 0, pc: 5] local: this index: 0 type: new ....java.erasure.Voodoo1(){}
...
}
166/171
Outline
 History
 Problem
 Special Case
 General Definitions
 Generics Definitions
– Parametric
Polymorphism
– Other Bounded
Parametric
Polymorphisms
 When to Use Generics
 How to Use Generics
 Caveats with Generics
 Reflecting on Generics
 Conclusion
 Few References
167/171
Conclusion
 Java generics
“Implement generic algorithms that work on
a collection of different types”
—The Java Tutorials, Oracle
168/171
Conclusion
 Scenario 1: you want to enforce type safety
for containers and remove the need for
typecasts when using these containers
 Scenario 2: you want to build generic
algorithms that work on several types of
(possible unrelated) things
169/171
Conclusion
 Easy to use in simple cases
 Some caveats, though
 Can be very tricky is corner cases
– Use them sparingly and purposefully
170/171
Outline
 History
 Problem
 Special Case
 General Definitions
 Generics Definitions
– Parametric
Polymorphism
– Other Bounded
Parametric
Polymorphisms
 When to Use Generics
 How to Use Generics
 Caveats with Generics
 Reflecting on Generics
 Conclusion
 Few References
171/171
Outline
 In no particular order
– http://en.wikipedia.org/wiki/Generics_in_Java
– http://www.angelikalanger.com/GenericsFAQ/FAQ
Sections/TechnicalDetails.html#FAQ502
– http://www.uio.no/studier/emner/matnat/ifi/INF3110/h05/
lysark/Types.pdf
– http://www.slideshare.net/SFilipp/java-puzzle-167104
– http://www.jquantlib.org/index.php/Using_TypeTokens_
to_retrieve_generic_parameters#Anonymous_classes
– http://www.clear.rice.edu/comp310/JavaResources/ generics/
– http://gafter.blogspot.kr/2006/12/super-type-tokens.html

More Related Content

Similar to On Java Generics, History, Use, Caveats v1.1

Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...Raffi Khatchadourian
 
Automated Refactoring of Legacy Java Software to Default Methods Talk at GMU
Automated Refactoring of Legacy Java Software to Default Methods Talk at GMUAutomated Refactoring of Legacy Java Software to Default Methods Talk at GMU
Automated Refactoring of Legacy Java Software to Default Methods Talk at GMURaffi Khatchadourian
 
Introduction
IntroductionIntroduction
Introductionrichsoden
 
PhD Presentation
PhD PresentationPhD Presentation
PhD Presentationmskayed
 
Introduction to new features in java 8
Introduction to new features in java 8Introduction to new features in java 8
Introduction to new features in java 8Raffi Khatchadourian
 
Agile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddAgile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddSrinivasa GV
 
Introducing generic types
Introducing generic typesIntroducing generic types
Introducing generic typesIvelin Yanev
 
Linq 1224887336792847 9
Linq 1224887336792847 9Linq 1224887336792847 9
Linq 1224887336792847 9google
 
CSER2016 - Detecting Problems in Database Access Code of Large Scale Systems
CSER2016 - Detecting Problems in Database Access Code of Large Scale SystemsCSER2016 - Detecting Problems in Database Access Code of Large Scale Systems
CSER2016 - Detecting Problems in Database Access Code of Large Scale SystemsConcordia University
 
JavaBasicsCore1.ppt
JavaBasicsCore1.pptJavaBasicsCore1.ppt
JavaBasicsCore1.pptbuvanabala
 
A brief overview of java frameworks
A brief overview of java frameworksA brief overview of java frameworks
A brief overview of java frameworksMD Sayem Ahmed
 
Java programming basics
Java programming basicsJava programming basics
Java programming basicsHamid Ghorbani
 
JavaScript Miller Columns
JavaScript Miller ColumnsJavaScript Miller Columns
JavaScript Miller ColumnsJonathan Fine
 
Code transformation With Spoon
Code transformation With SpoonCode transformation With Spoon
Code transformation With SpoonGérard Paligot
 
Resilience Engineering: A field of study, a community, and some perspective s...
Resilience Engineering: A field of study, a community, and some perspective s...Resilience Engineering: A field of study, a community, and some perspective s...
Resilience Engineering: A field of study, a community, and some perspective s...John Allspaw
 
Patterns in Python
Patterns in PythonPatterns in Python
Patterns in Pythondn
 

Similar to On Java Generics, History, Use, Caveats v1.1 (20)

Lect1.pptx
Lect1.pptxLect1.pptx
Lect1.pptx
 
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
 
Automated Refactoring of Legacy Java Software to Default Methods Talk at GMU
Automated Refactoring of Legacy Java Software to Default Methods Talk at GMUAutomated Refactoring of Legacy Java Software to Default Methods Talk at GMU
Automated Refactoring of Legacy Java Software to Default Methods Talk at GMU
 
Introduction
IntroductionIntroduction
Introduction
 
PhD Presentation
PhD PresentationPhD Presentation
PhD Presentation
 
Introduction to new features in java 8
Introduction to new features in java 8Introduction to new features in java 8
Introduction to new features in java 8
 
Introduction to new features in java 8
Introduction to new features in java 8Introduction to new features in java 8
Introduction to new features in java 8
 
Agile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddAgile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tdd
 
Introducing generic types
Introducing generic typesIntroducing generic types
Introducing generic types
 
Linq 1224887336792847 9
Linq 1224887336792847 9Linq 1224887336792847 9
Linq 1224887336792847 9
 
CSER2016 - Detecting Problems in Database Access Code of Large Scale Systems
CSER2016 - Detecting Problems in Database Access Code of Large Scale SystemsCSER2016 - Detecting Problems in Database Access Code of Large Scale Systems
CSER2016 - Detecting Problems in Database Access Code of Large Scale Systems
 
Java Unit 2(Part 1)
Java Unit 2(Part 1)Java Unit 2(Part 1)
Java Unit 2(Part 1)
 
JavaBasicsCore1.ppt
JavaBasicsCore1.pptJavaBasicsCore1.ppt
JavaBasicsCore1.ppt
 
A brief overview of java frameworks
A brief overview of java frameworksA brief overview of java frameworks
A brief overview of java frameworks
 
Java programming basics
Java programming basicsJava programming basics
Java programming basics
 
JavaScript Miller Columns
JavaScript Miller ColumnsJavaScript Miller Columns
JavaScript Miller Columns
 
Code transformation With Spoon
Code transformation With SpoonCode transformation With Spoon
Code transformation With Spoon
 
Resilience Engineering: A field of study, a community, and some perspective s...
Resilience Engineering: A field of study, a community, and some perspective s...Resilience Engineering: A field of study, a community, and some perspective s...
Resilience Engineering: A field of study, a community, and some perspective s...
 
J2SE 5
J2SE 5J2SE 5
J2SE 5
 
Patterns in Python
Patterns in PythonPatterns in Python
Patterns in Python
 

More from Yann-Gaël Guéhéneuc

Advice for writing a NSERC Discovery grant application v0.5
Advice for writing a NSERC Discovery grant application v0.5Advice for writing a NSERC Discovery grant application v0.5
Advice for writing a NSERC Discovery grant application v0.5Yann-Gaël Guéhéneuc
 
Ptidej Architecture, Design, and Implementation in Action v2.1
Ptidej Architecture, Design, and Implementation in Action v2.1Ptidej Architecture, Design, and Implementation in Action v2.1
Ptidej Architecture, Design, and Implementation in Action v2.1Yann-Gaël Guéhéneuc
 
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22Yann-Gaël Guéhéneuc
 
Consequences and Principles of Software Quality v0.3
Consequences and Principles of Software Quality v0.3Consequences and Principles of Software Quality v0.3
Consequences and Principles of Software Quality v0.3Yann-Gaël Guéhéneuc
 
Some Pitfalls with Python and Their Possible Solutions v0.9
Some Pitfalls with Python and Their Possible Solutions v0.9Some Pitfalls with Python and Their Possible Solutions v0.9
Some Pitfalls with Python and Their Possible Solutions v0.9Yann-Gaël Guéhéneuc
 
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...Yann-Gaël Guéhéneuc
 
An Explanation of the Halting Problem and Its Consequences
An Explanation of the Halting Problem and Its ConsequencesAn Explanation of the Halting Problem and Its Consequences
An Explanation of the Halting Problem and Its ConsequencesYann-Gaël Guéhéneuc
 
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)Informaticien(ne)s célèbres (v1.0.2, 19/02/20)
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)Yann-Gaël Guéhéneuc
 
On Reflection in OO Programming Languages v1.6
On Reflection in OO Programming Languages v1.6On Reflection in OO Programming Languages v1.6
On Reflection in OO Programming Languages v1.6Yann-Gaël Guéhéneuc
 

More from Yann-Gaël Guéhéneuc (20)

Advice for writing a NSERC Discovery grant application v0.5
Advice for writing a NSERC Discovery grant application v0.5Advice for writing a NSERC Discovery grant application v0.5
Advice for writing a NSERC Discovery grant application v0.5
 
Ptidej Architecture, Design, and Implementation in Action v2.1
Ptidej Architecture, Design, and Implementation in Action v2.1Ptidej Architecture, Design, and Implementation in Action v2.1
Ptidej Architecture, Design, and Implementation in Action v2.1
 
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
 
Consequences and Principles of Software Quality v0.3
Consequences and Principles of Software Quality v0.3Consequences and Principles of Software Quality v0.3
Consequences and Principles of Software Quality v0.3
 
Some Pitfalls with Python and Their Possible Solutions v0.9
Some Pitfalls with Python and Their Possible Solutions v0.9Some Pitfalls with Python and Their Possible Solutions v0.9
Some Pitfalls with Python and Their Possible Solutions v0.9
 
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...
 
An Explanation of the Halting Problem and Its Consequences
An Explanation of the Halting Problem and Its ConsequencesAn Explanation of the Halting Problem and Its Consequences
An Explanation of the Halting Problem and Its Consequences
 
Are CPUs VMs Like Any Others? v1.0
Are CPUs VMs Like Any Others? v1.0Are CPUs VMs Like Any Others? v1.0
Are CPUs VMs Like Any Others? v1.0
 
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)Informaticien(ne)s célèbres (v1.0.2, 19/02/20)
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)
 
Well-known Computer Scientists v1.0.2
Well-known Computer Scientists v1.0.2Well-known Computer Scientists v1.0.2
Well-known Computer Scientists v1.0.2
 
On Reflection in OO Programming Languages v1.6
On Reflection in OO Programming Languages v1.6On Reflection in OO Programming Languages v1.6
On Reflection in OO Programming Languages v1.6
 
ICSOC'21
ICSOC'21ICSOC'21
ICSOC'21
 
Vissoft21.ppt
Vissoft21.pptVissoft21.ppt
Vissoft21.ppt
 
Service computation20.ppt
Service computation20.pptService computation20.ppt
Service computation20.ppt
 
Serp4 iot20.ppt
Serp4 iot20.pptSerp4 iot20.ppt
Serp4 iot20.ppt
 
Msr20.ppt
Msr20.pptMsr20.ppt
Msr20.ppt
 
Iwesep19.ppt
Iwesep19.pptIwesep19.ppt
Iwesep19.ppt
 
Icsoc20.ppt
Icsoc20.pptIcsoc20.ppt
Icsoc20.ppt
 
Icsoc18.ppt
Icsoc18.pptIcsoc18.ppt
Icsoc18.ppt
 
Icsm20.ppt
Icsm20.pptIcsm20.ppt
Icsm20.ppt
 

Recently uploaded

Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Intelisync
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 

Recently uploaded (20)

Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 

On Java Generics, History, Use, Caveats v1.1

  • 1. Yann-Gaël Guéhéneuc Département de génie informatique et de génie logiciel This work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 3.0 Unported License Java Generics yann-gael.gueheneuc@polytmtl.ca Version 1.1 2014/05/12
  • 2. 2/171 Any questions/comments are welcome at yann-gael.gueheneuc@polymtl.ca Source code available at http://www.ptidej.net/tutorials/javagenerics
  • 3. 3/171 2013/03/22 – v1.0 – First version of the slides 2013/04/19 – v1.0.1 – Fixed some typos 2014/05/12 – v1.1 – Added example of mixing objects Cited PECS explanations Added more generated bytecodes Fixed some typos
  • 4. 4/171 Problem  Sorting lists does not and should not depend on the type of the elements stored in the list import java.util.List; public interface ISort { public List sort(final List aList); }
  • 5. 5/171 Problem  Sorting lists does not and should not depend on the type of the elements stored in the list Problem: elements may not be comparable Solution: generic typing with Comparable
  • 6. 6/171 Problem  Sorting lists assumes (and is sure) that the elements stored in the list are comparable import java.util.List; public interface ISort<E extends Comparable<E>> { public List<E> sort(final List<E> aList); }
  • 7. 7/171 Outline  History  Problem  Special Case  General Definitions  Generics Definitions – Parametric Polymorphism – Other Bounded Parametric Polymorphisms  When to Use Generics  How to Use Generics  Caveats with Generics  Reflecting on Generics  Conclusion  Few References
  • 8. 8/171 Outline  History  Problem  Special Case  General Definitions  Generics Definitions – Parametric Polymorphism – Other Bounded Parametric Polymorphisms  When to Use Generics  How to Use Generics  Caveats with Generics  Reflecting on Generics  Conclusion  Few References
  • 9. 9/171 History  1983: Reynolds formalises the parametricity theorem, called abstraction theorem – Functions with similar types have similar properties John C. Reynolds *1935 John C. Reynolds ; “Types, abstraction, and parametric polymorphism” ; Information Processing ; pp. 513–523, North Holland, 1983.
  • 10. 10/171 History  Parametric polymorphism – Expressiveness – Type-safety • First implementation in ML in 1989 (1976?) append: [a]  [a]  [a] Robin Milner, Robert Harper, David MacQueen, and Mads Tofte ; “The Definition Of Standard ML” ; The MIT Press, 1997.
  • 11. 11/171 History  Parametric polymorphism – Expressiveness – Type-safety • First implementation in ML in 1989 (1976?) append: [a]  [a]  [a] Robin Milner, Robert Harper, David MacQueen, and Mads Tofte ; “The Definition Of Standard ML” ; The MIT Press, 1997. Explicit parametric polymorphism
  • 12. 12/171 History  1988: David Musser and Alexander Stepanov define the concept of generic programming – Abstractions from examples of algorithms and data structure – Concept of “concept” David R. Musser and Alexander A. Stepanov ; “Generic Programming” ; International symposium on Symbolic and Algebraic Computation, pp. 13-25, ACM Press, 1988. Alexander Stepanov *1950 David Musser *c.1945
  • 13. 13/171 History “Generic programming is about abstracting and classifying algorithms and data structures. […] Its goal is the incremental construction of systematic catalogs of useful, efficient and abstract algorithms and data structures.” —Alexander Stepanov
  • 14. 14/171 History  Generic programming – Theory of iterators – Independent of implementation • C++ Standard Template Library (STL) const ::std::vector<Foo>::iterator theEnd = theContainer.end(); for ( ::std::vector<Foo>::iterator i = theContainer.begin(); i != theEnd; ++i ) { Foo &cur_element = *i; // Do something… }
  • 15. 15/171 History  1994: the GoF defines parameterized types “Also known as generics (Ada, Eiffel) and templates (C++)” “A type that leaves some constituent types unspecified. The unspecified types are supplied as parameters at the point of use.”
  • 16. 16/171 History  19771980: Ada – 2005: generic container library  1985: Eiffel Bertrand Meyer ; Object-Oriented Software Construction ; Prentice Hall, 1988.  1991: C++ http://www.stroustrup.com/hopl2.pdf – 1994: STL (under Stepanov’s guidance)  2004: Java – Type erasure  2005: C# – Reified generics
  • 17. 17/171 Outline  History  Problem  Special Case  General Definitions  Generics Definitions – Parametric Polymorphism – Other Bounded Parametric Polymorphisms  When to Use Generics  How to Use Generics  Caveats with Generics  Reflecting on Generics  Conclusion  Few References
  • 18. 18/171 Problem “Implement generic algorithms that work on a collection of different types” —The Java Tutorials, Oracle http://docs.oracle.com/javase/tutorial/java/generics/why.html
  • 19. 19/171 Problem  Sorting lists does not and should not depend on the type of the elements stored in the list import java.util.List; public interface ISort { public List sort(final List aList); }
  • 20. 20/171 Problem  Sorting lists does not and should not depend on the type of the elements stored in the list Problem: elements may not be comparable Solution: generic typing with Comparable
  • 21. 21/171 Problem  Sorting lists does not and should not depend on the type of the elements stored in the list import java.util.List; public interface ISort<E extends Comparable<E>> { public List<E> sort(final List<E> aList); }
  • 22. 22/171 Outline  History  Problem  Special Case  General Definitions  Generics Definitions – Parametric Polymorphism – Other Bounded Parametric Polymorphisms  When to Use Generics  How to Use Generics  Caveats with Generics  Reflecting on Generics  Conclusion  Few References
  • 23. 23/171 Special Case package net.ptidej.generics.java; public class Example1 { public static void main(final String[] args) { final Object[] arrayOfObjects = new Object[10]; final String[] arrayOfStrings = new String[20]; System.out.println(arrayOfObjects.length); System.out.println(arrayOfStrings.length); System.out.println(arrayOfObjects[0]); System.out.println(arrayOfStrings[2]); System.out.println(arrayOfObjects.clone()); System.out.println(arrayOfStrings.toString()); } }
  • 24. 24/171 Special Case  Array are (often) predefined generic types final Object[] arrayOfObjects = new Object[10]; final String[] arrayOfStrings = new String[20];
  • 25. 25/171 Special Case  Array are (often) predefined generic types final Object[] arrayOfObjects = new Object[10]; final String[] arrayOfStrings = new String[20]; Any type can go here
  • 26. 26/171 Special Case  Every new array instantiates a new concrete type (or reuse an existing concrete type)
  • 27. 27/171 Special Case  Every new array instantiates a new concrete type (or reuse an existing concrete type) New concrete type (pseudo-type in Java)
  • 28. 28/171 Special Case  Syntax and semantics built in the compiler System.out.println(arrayOfObjects.length); System.out.println(arrayOfStrings.length); System.out.println(arrayOfObjects[0]); System.out.println(arrayOfStrings[2]); System.out.println(arrayOfObjects.clone()); System.out.println(arrayOfStrings.toString());
  • 29. 29/171 Special Case  Syntax and semantics built in the compiler Pseudo-field System.out.println(arrayOfObjects.length); System.out.println(arrayOfStrings.length); System.out.println(arrayOfObjects[0]); System.out.println(arrayOfStrings[2]); System.out.println(arrayOfObjects.clone()); System.out.println(arrayOfStrings.toString());
  • 30. 30/171 Special Case  Syntax and semantics built in the compiler Pseudo-field System.out.println(arrayOfObjects.length); System.out.println(arrayOfStrings.length); System.out.println(arrayOfObjects[0]); System.out.println(arrayOfStrings[2]); System.out.println(arrayOfObjects.clone()); System.out.println(arrayOfStrings.toString()); Access, a[b]
  • 31. 31/171 Special Case  Syntax and semantics built in the compiler Pseudo-field System.out.println(arrayOfObjects.length); System.out.println(arrayOfStrings.length); System.out.println(arrayOfObjects[0]); System.out.println(arrayOfStrings[2]); System.out.println(arrayOfObjects.clone()); System.out.println(arrayOfStrings.toString()); Access, a[b] In the Java programming language arrays are objects (§4.3.1), are dynamically created, and may be assigned to variables of type Object (§4.3.2). All methods of class Object may be invoked on an array. —JLS
  • 32. 32/171 Outline  History  Problem  Special Case  General Definitions  Generics Definitions – Parametric Polymorphism – Other Bounded Parametric Polymorphisms  When to Use Generics  How to Use Generics  Caveats with Generics  Reflecting on Generics  Conclusion  Few References
  • 33. 33/171 General Definitions  Polymorphism – Ad-hoc polymorphism – Subtype polymorphism – Parametric polymorphism • Implicit • Explicit
  • 34. 34/171 General Definitions  Ad-hoc polymorphism – Method overloading – Not a feature of the type system – Dispatch mechanism • Typically, dispatch depends on the concrete type of the receiver of a method Christopher Strachey ; “Fundamental Concepts in Programming Languages” ; Higher-Order and Symbolic Computation, volume 13, issue 1-2, pp. 11-49, Springer, 2000.
  • 35. 35/171 General Definitions  Ad-hoc polymorphism – A name may have more than one meaning • It may refer to more than one algorithm – The choice of the algorithm is context- dependent but know at compile-time (Early binding when compared to the following subtype polymorphism)
  • 36. 36/171 General Definitions  Subtype polymorphism – Liskov substitution principle • Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T (Late binding when compared to the previous ad hoc polymorphism) Barbara Liskov *1939
  • 37. 37/171 General Definitions  Subtype polymorphism package net.ptidej.generics.java; import java.awt.Frame; import java.lang.Long; public class Example3 { public static void main(final String[] args) { Object o; o = new Long(1); System.out.println(o.toString()); o = new Frame(); System.out.println(o.toString()); } }
  • 38. 38/171 General Definitions  Subtype polymorphism package net.ptidej.generics.java; import java.awt.Frame; import java.lang.Long; public class Example3 { public static void main(final String[] args) { Object o; o = new Long(1); System.out.println(o.toString()); o = new Frame(); System.out.println(o.toString()); } } Declared type vs. concrete types
  • 39. 39/171 General Definitions  Parametric polymorphism public class NonGenericBox { private Object object; public void set(final Object object) { this.object = object; } public Object get() { return this.object; } } public void useOfNonGenericBox() { final NonGenericBox aNonGenericBox = new NonGenericBox(); aNonGenericBox.set(new String()); final String myString = (String) aNonGenericBox.get(); System.out.println(myString); }
  • 40. 40/171 General Definitions  Parametric polymorphism public class NonGenericBox { private Object object; public void set(final Object object) { this.object = object; } public Object get() { return this.object; } } public void useOfNonGenericBox() { final NonGenericBox aNonGenericBox = new NonGenericBox(); aNonGenericBox.set(new String()); final String myString = (String) aNonGenericBox.get(); System.out.println(myString); } Must cast to ask compiler to allow the assignment
  • 41. 41/171 General Definitions  Parametric polymorphism public class NonGenericBox { private Object object; public void set(final Object object) { this.object = object; } public Object get() { return this.object; } } public void useOfNonGenericBox() { final NonGenericBox aNonGenericBox = new NonGenericBox(); aNonGenericBox.set(new String()); final Integer myInteger = (Integer) aNonGenericBox.get(); System.out.println(myInteger); }
  • 42. 42/171 General Definitions  Parametric polymorphism public class NonGenericBox { private Object object; public void set(final Object object) { this.object = object; } public Object get() { return this.object; } } public void useOfNonGenericBox() { final NonGenericBox aNonGenericBox = new NonGenericBox(); aNonGenericBox.set(new String()); final Integer myInteger = (Integer) aNonGenericBox.get(); System.out.println(myInteger); } Legal!
  • 43. 43/171 General Definitions  Parametric polymorphism We use Java vocabulary in the following
  • 44. 44/171 General Definitions  Parametric polymorphism Type parameter We use Java vocabulary in the following
  • 45. 45/171 General Definitions  Parametric polymorphism Type parameter We use Java vocabulary in the following Type variable
  • 46. 46/171 General Definitions  Parametric polymorphism Type parameter Generic type declaration We use Java vocabulary in the following Type variable
  • 47. 47/171 General Definitions  Parametric polymorphism Type parameter Generic type declaration We use Java vocabulary in the following Parameterised methods Type variable
  • 48. 48/171 General Definitions  Parametric polymorphism Type parameter Generic type declaration We use Java vocabulary in the following Type argument Parameterised methods Type variable
  • 49. 49/171 General Definitions  Parametric polymorphism public class GenericBox<T> { private T t; public void set(final T t) { this.t = t; } public T get() { return this.t; } } public void useOfGenericBox() { final GenericBox<String> aGenericBox = new GenericBox<String>(); aGenericBox.set(new String()); final String myString = aGenericBox.get(); System.out.println(myString); }
  • 50. 50/171 General Definitions  Parametric polymorphism public class GenericBox<T> { private T t; public void set(final T t) { this.t = t; } public T get() { return this.t; } } public void useOfGenericBox() { final GenericBox<String> aGenericBox = new GenericBox<String>(); aGenericBox.set(new String()); final Integer myInteger = (Integer) aNonGenericBox.get(); System.out.println(myInteger); }
  • 51. 51/171 General Definitions  Parametric polymorphism public class GenericBox<T> { private T t; public void set(final T t) { this.t = t; } public T get() { return this.t; } } public void useOfGenericBox() { final GenericBox<String> aGenericBox = new GenericBox<String>(); aGenericBox.set(new String()); final Integer myInteger = (Integer) aNonGenericBox.get(); System.out.println(myInteger); } Illegal!
  • 52. 52/171 General Definitions  Parametric polymorphism package net.ptidej.generics.java; public class Example4 { public static void main(final String[] args) { System.out.println(Util.<String>compare("a", "b")); System.out.println(Util.<String>compare(new String(""), new Long(1))); System.out.println(Util.compare(new String(""), new Long(1))); } } public class Util { public static <T> boolean compare(T t1, T t2) { return t1.equals(t2); } }
  • 53. 53/171 General Definitions  Parametric polymorphism package net.ptidej.generics.java; public class Example4 { public static void main(final String[] args) { System.out.println(Util.<String>compare("a", "b")); System.out.println(Util.<String>compare(new String(""), new Long(1))); System.out.println(Util.compare(new String(""), new Long(1))); } } public class Util { public static <T> boolean compare(T t1, T t2) { return t1.equals(t2); } } Generic method
  • 54. 54/171 General Definitions  Parametric polymorphism package net.ptidej.generics.java; public class Example4 { public static void main(final String[] args) { System.out.println(Util.<String>compare("a", "b")); System.out.println(Util.<String>compare(new String(""), new Long(1))); System.out.println(Util.compare(new String(""), new Long(1))); } } public class Util { public static <T> boolean compare(T t1, T t2) { return t1.equals(t2); } } Generic method Explicit calls
  • 55. 55/171 General Definitions  Parametric polymorphism package net.ptidej.generics.java; public class Example4 { public static void main(final String[] args) { System.out.println(Util.<String>compare("a", "b")); System.out.println(Util.<String>compare(new String(""), new Long(1))); System.out.println(Util.compare(new String(""), new Long(1))); } } public class Util { public static <T> boolean compare(T t1, T t2) { return t1.equals(t2); } } Generic method Explicit calls Implicit call
  • 56. 56/171 Outline  History  Problem  Special Case  General Definitions  Generics Definitions – Parametric Polymorphism – Other Bounded Parametric Polymorphisms  When to Use Generics  How to Use Generics  Caveats with Generics  Reflecting on Generics  Conclusion  Few References
  • 57. 57/171 Generics Definitions “A generic type is a generic class or interface that is parameterized over types.” —The Java Tutorials, Oracle
  • 58. 58/171 Generics Definitions  Java generics are one implementation of parametric polymorphism – Type erasure  Type parameters can be constrained – Lower bounds – Upper bounds to obtain bounded type parameters
  • 59. 59/171 Outline  History  Problem  Special Case  General Definitions  Generics Definitions – Parametric Polymorphism – Other Bounded Parametric Polymorphisms  When to Use Generics  How to Use Generics  Caveats with Generics  Reflecting on Generics  Conclusion  Few References
  • 60. 60/171 Generics Definitions  Parametric polymorphism – Predicative • ML – Impredicative • System F • C++, Java 1.5 – Bounded • C++ in one way, Java 1.5 in another Martín Abadi, Luca Cardelli, Pierre-Louis Curien ; “Formal Parametric Polymorphism” ; SRC research report, issue 109, Digital, Systems Research Center, 1993.
  • 61. 61/171 Generics Definitions  Predicative parametric polymorphism – A type T containing a type variable  may not be used in such a way that  is instantiated to a polymorphic type
  • 62. 62/171 Generics Definitions  Predicative parametric polymorphism – A type T containing a type variable  may not be used in such a way that  is instantiated to a polymorphic type final GenericBox<String> aGenericBox = new GenericBox<String>(); aGenericBox.set(new String()); final GenericBox<List<String>> aGenericBox = new GenericBox<List<String>>(); aGenericBox.set(new String());
  • 63. 63/171 Generics Definitions  Predicative parametric polymorphism – A type T containing a type variable  may not be used in such a way that  is instantiated to a polymorphic type final GenericBox<String> aGenericBox = new GenericBox<String>(); aGenericBox.set(new String()); final GenericBox<List<String>> aGenericBox = new GenericBox<List<String>>(); aGenericBox.set(new String());
  • 64. 64/171 Generics Definitions  Impredicative parametric polymorphism – Example 1 – Example 2
  • 65. 65/171 Generics Definitions  Impredicative parametric polymorphism – Example 1 – Example 2 final GenericBox<List<String>> aGenericBox = new GenericBox<List<String>>(); aGenericBox.set(new String());
  • 66. 66/171 Generics Definitions  Impredicative parametric polymorphism – Example 1 – Example 2 import java.util.List; public interface ISort<E extends Comparable<E>> { public List<E> sort(final List<E> aList); } final GenericBox<List<String>> aGenericBox = new GenericBox<List<String>>(); aGenericBox.set(new String());
  • 67. 67/171 Generics Definitions  Bounded parametric polymorphism The type E of the list elements must implement the interface Comparable import java.util.List; public interface ISort<E extends Comparable<E>> { public List<E> sort(final List<E> aList); }
  • 68. 68/171 Generics Definitions  Bounded parametric polymorphism “Bounded genericity is less about limiting the types accepted by [a] generic class […] and more about giving the generic class a more complete information on its generic type T […] to validate the call to its methods at compile time.” —paercebal http://stackoverflow.com/questions/6803100/achieving-bounded-genericity-in-c/6803124
  • 69. 69/171 Generics Definitions public class Example5 { public static void main(final String[] args) { final Sort<A> sort = new Sort<A>(); final List<A> listOfAs = new ArrayList<A>(); sort.sort(listOfAs); System.out.println(); } } class Sort<E extends Comparable<E>> { public List<E> sort(final List<E> aList) { return // TO DO } } class A implements Comparable<A> { public int compareTo(final A o) { return // TO DO } } class B implements Comparable<B> { public int compareTo(final B o) { return // TO DO } }
  • 70. 70/171 Generics Definitions public class Example5 { public static void main(final String[] args) { final Sort<A> sort = new Sort<A>(); final List<A> listOfAs = new ArrayList<A>(); sort.sort(listOfAs); System.out.println(); } } class Sort<E extends Comparable<E>> { public List<E> sort(final List<E> aList) { return // TO DO } } class A implements Comparable<A> { public int compareTo(final A o) { return // TO DO } } class B implements Comparable<B> { public int compareTo(final B o) { return // TO DO } } Must be comparable (with itself)
  • 71. 71/171 Outline  History  Problem  Special Case  General Definitions  Generics Definitions – Parametric Polymorphism – Other Bounded Parametric Polymorphisms  When to Use Generics  How to Use Generics  Caveats with Generics  Reflecting on Generics  Conclusion  Few References
  • 72. 72/171 Generics Definitions  Other bounded parametric polymorphisms Java C++
  • 73. 73/171 Generics Definitions  Other bounded parametric polymorphisms “This feature is provided as-is and where-used by the compiler: in a way similar to duck typing, but resolved at compile-time. [Compilation succeeds] only if the generic type class [declares] the [expected method].” —paercebal http://stackoverflow.com/questions/6803100/achieving-bounded-genericity-in-c/6803124
  • 74. 74/171 Generics Definitions class X { public: virtual void kewl_method() { /* etc. */ } }; class Y: public X { public: virtual void kewl_method() { /* etc. */ } }; class Z { public: virtual void kewl_method() { /* etc. */ } }; class K { public: virtual void wazaa() { /* etc. */ } }; template<typename T> class A { public: void foo() { T t; t.kewl_method(); } };
  • 75. 75/171 Generics Definitions class X { public: virtual void kewl_method() { /* etc. */ } }; class Y: public X { public: virtual void kewl_method() { /* etc. */ } }; class Z { public: virtual void kewl_method() { /* etc. */ } }; class K { public: virtual void wazaa() { /* etc. */ } }; template<typename T> class A { public: void foo() { T t; t.kewl_method(); } }; No common type
  • 76. 76/171 Generics Definitions class X { public: virtual void kewl_method() { /* etc. */ } }; class Y: public X { public: virtual void kewl_method() { /* etc. */ } }; class Z { public: virtual void kewl_method() { /* etc. */ } }; class K { public: virtual void wazaa() { /* etc. */ } }; template<typename T> class A { public: void foo() { T t; t.kewl_method(); } }; Common API
  • 77. 77/171 Generics Definitions int main() { // A's constraint is : implements kewl_method A<X> x ; x.foo() ; // OK: x implements kewl_method A<Y> y ; y.foo() ; // OK: y derives from X A<Z> z ; z.foo() ; // OK: z implements kewl_method A<K> k ; k.foo() ; // NOT OK : K won't compile: /main.cpp error: // ‘class K’ has no member named ‘kewl_method’ return 0; }
  • 78. 78/171 Generics Definitions “Static” duct typing int main() { // A's constraint is : implements kewl_method A<X> x ; x.foo() ; // OK: x implements kewl_method A<Y> y ; y.foo() ; // OK: y derives from X A<Z> z ; z.foo() ; // OK: z implements kewl_method A<K> k ; k.foo() ; // NOT OK : K won't compile: /main.cpp error: // ‘class K’ has no member named ‘kewl_method’ return 0; }
  • 79. 79/171 Generics Definitions  Duck typing – Dynamically-typed languages: Smalltalk – Statically-typed language: C++ “When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.” —Alex Martelli or James W. Riley
  • 80. 80/171 Generics Definitions  Dynamically-typed languages: Smalltalk Object subclass: #D instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'CSE3009'. D compile: 'needAFooMethod: anObjectWithaFooMethod "Example of duck typing" anObjectWithaFooMethod foo.'.
  • 81. 81/171 Generics Definitions  Dynamically-typed languages: Smalltalk Object subclass: #D instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'CSE3009'. D compile: 'needAFooMethod: anObjectWithaFooMethod "Example of duck typing" anObjectWithaFooMethod foo.'. Any object with a foo method will do
  • 82. 82/171 Generics Definitions  Dynamically-typed languages: Smalltalk SMUtilities subclass: #D1 instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'CSE3009'. D1 compile: 'foo Transcript show: ''D1'' ; cr.'. PointArray variableWordSubclass: #D2 instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'CSE3009'. D2 compile: 'foo Transcript show: ''D2'' ; cr.'.
  • 83. 83/171 Generics Definitions  Dynamically-typed languages: Smalltalk SMUtilities subclass: #D1 instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'CSE3009'. D1 compile: 'foo Transcript show: ''D1'' ; cr.'. PointArray variableWordSubclass: #D2 instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'CSE3009'. D2 compile: 'foo Transcript show: ''D2'' ; cr.'. Two unrelated classes
  • 84. 84/171 Generics Definitions  Dynamically-typed languages: Smalltalk d := D new. d needAFooMethod: (D1 new). d needAFooMethod: (D2 new). D1 D2
  • 85. 85/171 Outline  History  Problem  Special Case  General Definitions  Generics Definitions – Parametric Polymorphism – Other Bounded Parametric Polymorphisms  When to Use Generics  How to Use Generics  Caveats with Generics  Reflecting on Generics  Conclusion  Few References
  • 86. 86/171 When to Use Generics  Scenario 1: you want to enforce type safety for containers and remove the need for typecasts when using these containers public final class Example1 { public static void main(final String[] args) { final List untypedList = new ArrayList(); untypedList.add(new String()); final Integer i = (Integer) untypedList.get(0); final List<String> typedList = new ArrayList<String>(); typedList.add(new String()); final Integer i = (Integer) typedList.get(0); } } Does not compile
  • 87. 87/171 When to Use Generics  Scenario 2: you want to build generic algorithms that work on several types of (possible unrelated) things import java.util.List; public interface ISort<E extends Comparable<E>> { public List<E> sort(final List<E> aList); }
  • 88. 88/171 Outline  History  Problem  Special Case  General Definitions  Generics Definitions – Parametric Polymorphism – Other Bounded Parametric Polymorphisms  When to Use Generics  How to Use Generics  Caveats with Generics  Reflecting on Generics  Conclusion  Few References
  • 89. 89/171 How to Use Generics  Lots of resources  Lots of discussions  First step http://docs.oracle.com/javase/ tutorial/java/generics/index.html  Then, http://stackoverflow.com/search? q=%22java+generics%22 – 1,323 results as of 2013/04/14
  • 90. 90/171 How to Use Generics  Typed containers, before import java.util.ArrayList; import java.util.List; public final class Example1Before { public static void main(final String[] args) { final List untypedList = new ArrayList(); untypedList.add(new String()); final Integer i = (Integer) untypedList.get(0); } }
  • 91. 91/171 How to Use Generics  Typed containers, what happens? import java.util.ArrayList; import java.util.List; public final class Example1Before { public static void main(final String[] args) { final List untypedList = new ArrayList(); untypedList.add(new String()); final Integer i = (Integer) untypedList.get(0); } }
  • 92. 92/171 How to Use Generics  Typed containers, what happens? import java.util.ArrayList; import java.util.List; public final class Example1Before { public static void main(final String[] args) { final List untypedList = new ArrayList(); untypedList.add(new String()); final Integer i = (Integer) untypedList.get(0); } } Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer at net.ptidej.generics.java.Example1Before.main(Example1Before.java:29)
  • 93. 93/171 How to Use Generics  Typed containers, another look import java.util.ArrayList; import java.util.List; public final class Example1Before { public static void main(final String[] args) { final List untypedList = new ArrayList(); untypedList.add(new String()); final Integer i = (Integer) untypedList.get(0); } }
  • 94. 94/171 How to Use Generics  Typed containers, another look import java.util.ArrayList; import java.util.List; public final class Example1Before { public static void main(final String[] args) { final List untypedList = new ArrayList(); untypedList.add(new String()); final Integer i = (Integer) untypedList.get(0); } } List and ArrayList are raw types, compiler cannot typecheck
  • 95. 95/171 How to Use Generics  Typed containers, solution import java.util.ArrayList; import java.util.List; public final class Example1Before { public static void main(final String[] args) { final List<String> typedList = new ArrayList<String>(); typedList.add(new String()); final Integer i = (Integer) typedList.get(0); } }
  • 96. 96/171 How to Use Generics  Typed containers, solution import java.util.ArrayList; import java.util.List; public final class Example1Before { public static void main(final String[] args) { final List<String> typedList = new ArrayList<String>(); typedList.add(new String()); final Integer i = (Integer) typedList.get(0); } } Does not compile because String and Interger are not compatible
  • 97. 97/171 How to Use Generics  Family of algorithms, before public interface Enumeration { /** * Tests if this enumeration contains more elements. * * @return <code>true</code> if and only if this enumeration object * contains at least one more element to provide; * <code>false</code> otherwise. */ boolean hasMoreElements(); /** * Returns the next element of this enumeration if this enumeration * object has at least one more element to provide. * * @return the next element of this enumeration. * @exception NoSuchElementException if no more elements exist. */ Object nextElement(); }
  • 98. 98/171 How to Use Generics  Family of algorithms, what happens? public interface Enumeration { /** * Tests if this enumeration contains more elements. * * @return <code>true</code> if and only if this enumeration object * contains at least one more element to provide; * <code>false</code> otherwise. */ boolean hasMoreElements(); /** * Returns the next element of this enumeration if this enumeration * object has at least one more element to provide. * * @return the next element of this enumeration. * @exception NoSuchElementException if no more elements exist. */ Object nextElement(); }
  • 99. 99/171 How to Use Generics  Family of algorithms, what happens? public interface Enumeration { /** * Tests if this enumeration contains more elements. * * @return <code>true</code> if and only if this enumeration object * contains at least one more element to provide; * <code>false</code> otherwise. */ boolean hasMoreElements(); /** * Returns the next element of this enumeration if this enumeration * object has at least one more element to provide. * * @return the next element of this enumeration. * @exception NoSuchElementException if no more elements exist. */ Object nextElement(); } Forces clients to use Object
  • 100. 100/171 How to Use Generics  Family of algorithms, another look public interface Enumeration { /** * Tests if this enumeration contains more elements. * * @return <code>true</code> if and only if this enumeration object * contains at least one more element to provide; * <code>false</code> otherwise. */ boolean hasMoreElements(); /** * Returns the next element of this enumeration if this enumeration * object has at least one more element to provide. * * @return the next element of this enumeration. * @exception NoSuchElementException if no more elements exist. */ Object nextElement(); }
  • 101. 101/171 How to Use Generics  Family of algorithms, another look public interface Enumeration { /** * Tests if this enumeration contains more elements. * * @return <code>true</code> if and only if this enumeration object * contains at least one more element to provide; * <code>false</code> otherwise. */ boolean hasMoreElements(); /** * Returns the next element of this enumeration if this enumeration * object has at least one more element to provide. * * @return the next element of this enumeration. * @exception NoSuchElementException if no more elements exist. */ Object nextElement(); } Clients must know the type of the next element
  • 102. 102/171 How to Use Generics  Family of algorithms, solution public interface Enumeration<E> { /** * Tests if this enumeration contains more elements. * * @return <code>true</code> if and only if this enumeration object * contains at least one more element to provide; * <code>false</code> otherwise. */ boolean hasMoreElements(); /** * Returns the next element of this enumeration if this enumeration * object has at least one more element to provide. * * @return the next element of this enumeration. * @exception NoSuchElementException if no more elements exist. */ E nextElement(); }
  • 103. 103/171 How to Use Generics  Family of algorithms, solution public interface Enumeration<E> { /** * Tests if this enumeration contains more elements. * * @return <code>true</code> if and only if this enumeration object * contains at least one more element to provide; * <code>false</code> otherwise. */ boolean hasMoreElements(); /** * Returns the next element of this enumeration if this enumeration * object has at least one more element to provide. * * @return the next element of this enumeration. * @exception NoSuchElementException if no more elements exist. */ E nextElement(); }
  • 104. 104/171 How to Use Generics  Family of algorithms, solution public interface Enumeration<E> { /** * Tests if this enumeration contains more elements. * * @return <code>true</code> if and only if this enumeration object * contains at least one more element to provide; * <code>false</code> otherwise. */ boolean hasMoreElements(); /** * Returns the next element of this enumeration if this enumeration * object has at least one more element to provide. * * @return the next element of this enumeration. * @exception NoSuchElementException if no more elements exist. */ E nextElement(); } Clients can specify the type of the next element
  • 105. 105/171 Outline  History  Problem  Special Case  General Definitions  Generics Definitions – Parametric Polymorphism – Other Bounded Parametric Polymorphisms  When to Use Generics  How to Use Generics  Caveats with Generics  Reflecting on Generics  Conclusion  Few References
  • 106. 106/171 Caveats with Generics  ints and Integers, before public interface List extends Collection { ... boolean add(Object o); boolean remove(Object o); Object remove(int index); ... }
  • 107. 107/171 Caveats with Generics  ints and Integers, now public interface List<E> extends Collection<E> { ... boolean add(E e); boolean remove(Object o); E remove(int index); ... }
  • 108. 108/171 Caveats with Generics  ints and Integers, now public interface List<E> extends Collection<E> { ... boolean add(E e); boolean remove(Object o); E remove(int index); ... }
  • 109. 109/171 Caveats with Generics  ints and Integers, what happens? import java.util.ArrayList; import java.util.List; public class Autoboxing { public static void main(String[] args) { final List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(new Integer(2)); list.remove(1); list.remove(new Integer(1)); System.out.println(list.size()); } }
  • 110. 110/171 Caveats with Generics  ints and Integers, what happens? import java.util.ArrayList; import java.util.List; public class Autoboxing { public static void main(String[] args) { final List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(new Integer(2)); list.remove(1); list.remove(new Integer(1)); System.out.println(list.size()); } } Autoboxing from int to Integer
  • 111. 111/171 Caveats with Generics  ints and Integers, what happens? import java.util.ArrayList; import java.util.List; public class Autoboxing { public static void main(String[] args) { final List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(new Integer(2)); list.remove(1); list.remove(new Integer(1)); System.out.println(list.size()); } } Autoboxing from int to Integer Exact parameter matching takes over autoboxing
  • 112. 112/171 Caveats with Generics  ints and Integers, what happens? import java.util.ArrayList; import java.util.List; public class Autoboxing { public static void main(String[] args) { final List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(new Integer(2)); list.remove(1); list.remove(new Integer(1)); System.out.println(list.size()); } } Autoboxing from int to Integer Exact parameter matching takes over autoboxing 0
  • 113. 113/171 Caveats with Generics  Use of clone(), before http://stackoverflow.com/questions/3941850/ java-how-to-use-clone-and-what-about-the-cast-check import java.util.ArrayList; public class CloningBefore { public static void main(final String[] args) { final ArrayList list1 = new ArrayList(); list1.add(new Integer(1)); list1.add(new Integer(2)); final ArrayList list2 = (ArrayList) list1.clone(); System.out.println(list2); } }
  • 114. 114/171 Caveats with Generics  Use of clone(), before http://stackoverflow.com/questions/3941850/ java-how-to-use-clone-and-what-about-the-cast-check import java.util.ArrayList; public class CloningBefore { public static void main(final String[] args) { final ArrayList list1 = new ArrayList(); list1.add(new Integer(1)); list1.add(new Integer(2)); final ArrayList list2 = (ArrayList) list1.clone(); System.out.println(list2); } } No complains for the compiler
  • 115. 115/171 Caveats with Generics  Use of clone(), now import java.util.ArrayList; public class CloningNow { public static void main(final String[] args) { final ArrayList<Integer> list1 = new ArrayList<Integer>(); list1.add(1); list1.add(new Integer(2)); final ArrayList<Integer> list2 = (ArrayList<Integer>) list1.clone(); System.out.println(list2); } }
  • 116. 116/171 Caveats with Generics  Use of clone(), now import java.util.ArrayList; public class CloningNow { public static void main(final String[] args) { final ArrayList<Integer> list1 = new ArrayList<Integer>(); list1.add(1); list1.add(new Integer(2)); final ArrayList<Integer> list2 = (ArrayList<Integer>) list1.clone(); System.out.println(list2); } }
  • 117. 117/171 Caveats with Generics  Use of clone(), now import java.util.ArrayList; public class CloningNow { public static void main(final String[] args) { final ArrayList<Integer> list1 = new ArrayList<Integer>(); list1.add(1); list1.add(new Integer(2)); final ArrayList<Integer> list2 = (ArrayList<Integer>) list1.clone(); System.out.println(list2); } } Type safety: Unchecked cast from Object to ArrayList<Integer>
  • 118. 118/171 Caveats with Generics  Use of clone(), what happens? – Compiler is now “stricter” – Compiler warns of a type-unsafe operation
  • 119. 119/171 Caveats with Generics  Use of clone(), solution – Use copy-constructor to obtain type-safety and remove any warning import java.util.ArrayList; public class CloningSolution { public static void main(final String[] args) { final ArrayList<Integer> list1 = new ArrayList<Integer>(); list1.add(1); list1.add(new Integer(2)); final ArrayList<Integer> list2 = new ArrayList<Integer>(list1); System.out.println(list2); } }
  • 120. 120/171 Caveats with Generics  Use of clone(), solution – Use copy-constructor to obtain type-safety and remove any warning import java.util.ArrayList; public class CloningSolution { public static void main(final String[] args) { final ArrayList<Integer> list1 = new ArrayList<Integer>(); list1.add(1); list1.add(new Integer(2)); final ArrayList<Integer> list2 = new ArrayList<Integer>(list1); System.out.println(list2); } }
  • 121. 121/171 Caveats with Generics  Use of clone(), solution – Suppress warning public class CloningSolutionWarning { public static void main(final String[] args) { final ArrayList<Integer> list1 = new ArrayList<Integer>(); list1.add(1); list1.add(new Integer(2)); @SuppressWarnings("unchecked") final ArrayList<Integer> list2 = (ArrayList<Integer>) list1.clone(); System.out.println(list2); } }
  • 122. 122/171 Caveats with Generics  Use of clone(), solution – Suppress warning … not really a solution! public class CloningSolutionWarning { public static void main(final String[] args) { final ArrayList<Integer> list1 = new ArrayList<Integer>(); list1.add(1); list1.add(new Integer(2)); @SuppressWarnings("unchecked") final ArrayList<Integer> list2 = (ArrayList<Integer>) list1.clone(); System.out.println(list2); } }
  • 123. 123/171 Caveats with Generics  Instantiating a type variable, problem public class InstantiatingTypeParameterProblem<T> { public static void main(final String[] args) { ... } public T getInstanceOfT (){ // Neither lines work: return new T(); return T.newInstance(); } ... }
  • 124. 124/171 Caveats with Generics  Instantiating a type variable, problem public class InstantiatingTypeParameterProblem<T> { public static void main(final String[] args) { ... } public T getInstanceOfT (){ // Neither lines work: return new T(); return T.newInstance(); } ... } Cannot instantiate the type T
  • 125. 125/171 Caveats with Generics  Instantiating a type variable, problem public class InstantiatingTypeParameterProblem<T> { public static void main(final String[] args) { ... } public T getInstanceOfT (){ // Neither lines work: return new T(); return T.newInstance(); } ... } Cannot instantiate the type T The method newInstance() is undefined for the type T
  • 126. 126/171 Caveats with Generics  Instantiating a type variable, what happens? The type parameter T is erased at compile-time, the JVM cannot use it at run-time public class InstantiatingTypeParameterProblem<T> { public static void main(final String[] args) { ... } public T getInstanceOfT (){ // Neither lines work: return new T(); return T.newInstance(); } ... }
  • 127. 127/171 Caveats with Generics  Instantiating a type variable, solution #1 – Pass the class of T as parameter public class InstantiatingTypeParameterSolution1<T> { public static void main(final String[] args) { ... } public T getInstanceOfT(final Class<T> classOfT) { return classOfT.newInstance(); } ... }
  • 128. 128/171 Caveats with Generics  Instantiating a type variable, solution #2 – Pass a factory of T as parameter interface Factory<T> { T getInstance(); } class Something { public static class FactoryOfSomething implements Factory<Something> { public Something getInstance() { return new Something(); } } } public class InstantiatingTypeParameterSolution2<T> { public static void main(final String[] args) { ... } public T getInstanceOfT(final Factory<T> factory) { return factory.getInstance(); } ... }
  • 129. 129/171 Caveats with Generics  Instantiating a type variable, solution #3 – Prevent type erasure by specialising an interesting class public class InstantiatingTypeParameterSolution3 extends GenericClass<String> { public static void main(final String[] args) { final InstantiatingTypeParameterSolution3 i = new InstantiatingTypeParameterSolution3(); i.foo(); } public void foo() { final Object s = this.getInstanceOfT(); System.out.println(s.getClass()); } }
  • 130. 130/171 Caveats with Generics  Instantiating a type variable, solution #3 – Prevent type erasure by specialising an interesting class public class InstantiatingTypeParameterSolution3 extends GenericClass<String> { public static void main(final String[] args) { final InstantiatingTypeParameterSolution3 i = new InstantiatingTypeParameterSolution3(); i.foo(); } public void foo() { final Object s = this.getInstanceOfT(); System.out.println(s.getClass()); } } Type argument and subclassing
  • 131. 131/171 Caveats with Generics  Instantiating a type variable, solution #3 – Prevent type erasure by specialising an interesting class import java.lang.reflect.ParameterizedType; abstract class GenericClass<T> { public T getInstanceOfT() { final ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); final String parameterClassName = pt.getActualTypeArguments()[0].toString().split("s")[1]; T parameter = (T) Class.forName(parameterClassName).newInstance(); return parameter; } }
  • 132. 132/171 Caveats with Generics  Instantiating a type variable, solution #3 – Prevent type erasure by specialising an interesting class import java.lang.reflect.ParameterizedType; abstract class GenericClass<T> { public T getInstanceOfT() { final ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); final String parameterClassName = pt.getActualTypeArguments()[0].toString().split("s")[1]; T parameter = (T) Class.forName(parameterClassName).newInstance(); return parameter; } } The superclass is generic, the subclass specialises it
  • 133. 133/171 Caveats with Generics  Implicit generic methods – As with explicit generic methods, use Object in the generated bytecodes public final class Example4 { public static void main(final String[] args) { System.out.println(Util4.<String> compare("a", "b")); // The following line, as expected, produces a type mismatch error // System.out.println(Util.<String> compare(new String(""), new Long(1))); System.out.println(Util4.compare(new String(""), new Long(1))); } } final class Util4 { public static <T> boolean compare(final T t1, final T t2) { return t1.equals(t2); } }
  • 134. 134/171 Caveats with Generics  Implicit generic methods – As with explicit generic methods, use Object in the generated bytecodes to ensure backward-compatibility with non-generic Java code // Method descriptor #15 ([Ljava/lang/String;)V // Stack: 7, Locals: 1 public static void main(java.lang.String[] args); … 14 invokevirtual net.ptidej.generics.java.Util44.compare(java.lang.Object, java.lang.Object) : boolean [29] … 47 invokevirtual net.ptidej.generics.java.Util44.compare(java.lang.Object, java.lang.Object) : boolean [29] …
  • 135. 135/171 Caveats with Generics  Multiple bounds “A type variable with multiple bounds is a subtype of all the types listed in the bound. If one of the bounds is a class, it must be specified first.” —The Java Tutorials, Oracle
  • 136. 136/171 Caveats with Generics  Multiple bounds class Example8A { } interface Example8B { } interface Example8C { } class Example8D<T extends Example8A & Example8B & Example8C> { } class Example8Test1 extends Example8A implements Example8B, Example8C { } class Example8Test2 extends Example8A { } public class Example8 { public static void main(final String[] args) { final Example8D<Example8Test1> d1 = new Example8D<Example8Test1>(); final Example8D<Example8Test2> d2 = new Example8D<Example8Test2>(); } }
  • 137. 137/171 Caveats with Generics  Multiple bounds class Example8A { } interface Example8B { } interface Example8C { } class Example8D<T extends Example8A & Example8B & Example8C> { } class Example8Test1 extends Example8A implements Example8B, Example8C { } class Example8Test2 extends Example8A { } public class Example8 { public static void main(final String[] args) { final Example8D<Example8Test1> d1 = new Example8D<Example8Test1>(); final Example8D<Example8Test2> d2 = new Example8D<Example8Test2>(); } } Bound mismatch: The type Test2 is not a valid substitute for the bounded parameter <T extends …>
  • 138. 138/171 Caveats with Generics  Upper- and lower-bounded wildcards – Type parameters can be constrained to be • Any subtype of a type, extends • Any supertype of a type, super – Useful with collections of items import java.util.List; public interface ISort<E extends Comparable<E>> { public List<E> sort(final List<E> aList); }
  • 139. 139/171 Caveats with Generics  PECS – Collections that produce extends – Collections that consume super Always from the point of view of the collection http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs
  • 140. 140/171 Caveats with Generics  PECS – Collections that produce extends • They produce elements of some types • These types must be “topped” to tell the client that it can safely expect to receive Somthing • Any item from the collection is a Somthing (in the sense of Liskov’s substitution) Collection<? extends Something>
  • 141. 141/171 Caveats with Generics  PECS – Collections that consume super • They consume elements of some types • These types must be “bottomed” to tell the client that it can safely put Something • Any item in the collection is “at most” Something (in the sense of Liskov’s substitution) Collection<? super Something>
  • 142. 142/171 Caveats with Generics  PECS Another way to remember the producer / consumer distinction is to think of a method signature. If you have a method useList(List), you are consuming the List and so need covariance / extends. If your method is List buildList(), then you are producing the List and will need contravariance / super —Adapted from Raman http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs
  • 143. 143/171 Caveats with Generics  PECS – Collections that produce and consume must just use one type parameter • Not legal to combine extends and super Collection<Something>
  • 144. 144/171 Caveats with Generics  Ambiguity between parameterised types http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs public class Example9 { public static String f(List<String> list) { System.out.println("strings"); return null; } public static Integer f(List<Integer> list) { System.out.println("numbers"); return null; } public static void main(String[] args) { f(Arrays.asList("asdf")); f(Arrays.asList(123)); } }
  • 145. 145/171 Caveats with Generics  Ambiguity between parameterised types http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs public class Example9 { public static String f(List<String> list) { System.out.println("strings"); return null; } public static Integer f(List<Integer> list) { System.out.println("numbers"); return null; } public static void main(String[] args) { f(Arrays.asList("asdf")); f(Arrays.asList(123)); } } Legality depends on compiler • Eclipse 3.5 says yes • Eclipse 3.6 says no • Intellij 9 says yes • Sun javac 1.6.0_20 says yes • GCJ 4.4.3 says yes • GWT compiler says yes • Crowd says no
  • 146. 146/171 Outline  History  Problem  Special Case  General Definitions  Generics Definitions – Parametric Polymorphism – Other Bounded Parametric Polymorphisms  When to Use Generics  How to Use Generics  Caveats with Generics  Reflecting on Generics  Conclusion  Few References
  • 147. 147/171 Reflecting on Generics  Java generics use type erasure – (Most) Type parameters / arguments are erased at compile-time and exist at run-time only as annotations – Ensure backward-compatibility with pre-generic Java code – Limit access to type parameters / arguments using reflection
  • 148. 148/171 Caveats with Generics  Type-safe use of getClass() http://stackoverflow.com/questions/11060491/ is-there-a-clean-way-to-assign-the-class-of-a-generic-type-to-a-variable class Example11A { } public class Example11 { public static void main(final String[] args) { final Example11A anA1 = new Example11A(); final Class<Example11A> anA1Class = (Class<Example11A>) anA1.getClass(); System.out.println(anA1Class); final Example11A anA2 = new Example11A(); final Class<? extends Example11A> anA2Class = anA2.getClass(); System.out.println(anA2Class); } }
  • 149. 149/171 Caveats with Generics  Type-safe use of getClass() http://stackoverflow.com/questions/11060491/ is-there-a-clean-way-to-assign-the-class-of-a-generic-type-to-a-variable class Example11A { } public class Example11 { public static void main(final String[] args) { final Example11A anA1 = new Example11A(); final Class<Example11A> anA1Class = (Class<Example11A>) anA1.getClass(); System.out.println(anA1Class); final Example11A anA2 = new Example11A(); final Class<? extends Example11A> anA2Class = anA2.getClass(); System.out.println(anA2Class); } } Type safety: Unchecked cast from Class<capture#1-of ? extends Example11A> to Class<Example11A>
  • 150. 150/171 Caveats with Generics  Type-safe use of getClass() http://stackoverflow.com/questions/11060491/ is-there-a-clean-way-to-assign-the-class-of-a-generic-type-to-a-variable class Example11A { } public class Example11 { public static void main(final String[] args) { final Example11A anA1 = new Example11A(); final Class<Example11A> anA1Class = (Class<Example11A>) anA1.getClass(); System.out.println(anA1Class); final Example11A anA2 = new Example11A(); final Class<? extends Example11A> anA2Class = anA2.getClass(); System.out.println(anA2Class); } } Type safety: Unchecked cast from Class<capture#1-of ? extends Example11A> to Class<Example11A> No warning
  • 151. 151/171 Caveats with Generics  Type-safe use of getClass() class MyList extends ArrayList<Integer> { } public class Example11 { public static void main(final String[] args) { final List<Integer> list1 = new ArrayList<Integer>(); final Class<List<Integer>> list1Class = (Class<List<Integer>>) list1.getClass(); System.out.println(list1Class); final MyList list2 = new MyList(); Class<? extends List<? extends Integer>> list2Class = list2.getClass(); System.out.println(list2Class); } } http://stackoverflow.com/questions/11060491/ is-there-a-clean-way-to-assign-the-class-of-a-generic-type-to-a-variable
  • 152. 152/171 Caveats with Generics  Type-safe use of getClass() class MyList extends ArrayList<Integer> { } public class Example11 { public static void main(final String[] args) { final List<Integer> list1 = new ArrayList<Integer>(); final Class<List<Integer>> list1Class = (Class<List<Integer>>) list1.getClass(); System.out.println(list1Class); final MyList list2 = new MyList(); Class<? extends List<? extends Integer>> list2Class = list2.getClass(); System.out.println(list2Class); } } Type safety: Unchecked cast from Class<capture#4-of ? extends List> to Class<List<Integer>> http://stackoverflow.com/questions/11060491/ is-there-a-clean-way-to-assign-the-class-of-a-generic-type-to-a-variable
  • 153. 153/171 Caveats with Generics  Type-safe use of getClass() class MyList extends ArrayList<Integer> { } public class Example11 { public static void main(final String[] args) { final List<Integer> list1 = new ArrayList<Integer>(); final Class<List<Integer>> list1Class = (Class<List<Integer>>) list1.getClass(); System.out.println(list1Class); final MyList list2 = new MyList(); Class<? extends List<? extends Integer>> list2Class = list2.getClass(); System.out.println(list2Class); } } Type safety: Unchecked cast from Class<capture#4-of ? extends List> to Class<List<Integer>> No warning http://stackoverflow.com/questions/11060491/ is-there-a-clean-way-to-assign-the-class-of-a-generic-type-to-a-variable
  • 154. 154/171 Caveats with Generics  Use of newInstance() http://stackoverflow.com/questions/2592642/type-safety-unchecked-cast-from-object class Example10A { } public class Example10 { public static void main(final String[] args) { final Class<Example10A> clazz1 = Example10A.class; final Example10A anA1 = clazz1.newInstance(); System.out.println(anA1); final Class<?> clazz2 = Class.forName( "net.ptidej.generics.java.Example9A"); final Example10A anA2 = (Example10A) clazz2.newInstance(); System.out.println(anA2); } }
  • 155. 155/171 Caveats with Generics  Obtaining the type of a type parameter – Due to type erasure • Type parameters are kept as annotations • Type arguments disappear Except for anonymous/local classes! http://stackoverflow.com/questions/1901164/ get-type-of-a-generic-parameter-in-java-with-reflection
  • 156. 156/171 Caveats with Generics  Obtaining the type of a type parameter public final class Voodoo0 extends TestCase { public static void chill(final List<?> aListWithSomeType) { CommonTest.assertNotEqualAsExpected( aListWithSomeType, SpiderManVoodoo0.class); } public static void main(String... args) { Voodoo0.chill(new ArrayList<SpiderManVoodoo0>()); } public void test() { Voodoo0.main(new String[0]); } } class SpiderManVoodoo0 { }
  • 157. 157/171 Caveats with Generics  Obtaining the type of a type parameter public final class Voodoo0 extends TestCase { public static void chill(final List<?> aListWithSomeType) { CommonTest.assertNotEqualAsExpected( aListWithSomeType, SpiderManVoodoo0.class); } public static void main(String... args) { Voodoo0.chill(new ArrayList<SpiderManVoodoo0>()); } public void test() { Voodoo0.main(new String[0]); } } class SpiderManVoodoo0 { }
  • 158. 158/171 Caveats with Generics  Obtaining the type of a type parameter public static void main(java.lang.String...); flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS Code: stack=2, locals=1, args_size=1 0: new #32 // class java/util/ArrayList 3: dup 4: invokespecial #34 // Method java/util/ArrayList."<init>":()V 7: invokestatic #35 // Method chill:(Ljava/util/List;)V 10: return LineNumberTable: line 38: 0 line 39: 10 LocalVariableTable: Start Length Slot Name Signature 0 11 0 args [Ljava/lang/String;
  • 159. 159/171 Caveats with Generics  Obtaining the type of a type parameter public final class Voodoo1 extends TestCase { public static void chill(final List<?> aListWithSomeType) { CommonTest.assertNotEqualAsExpected( aListWithSomeType, SpiderManVoodoo1.class); } public static void main(String... args) { Voodoo1.chill(new ArrayList<SpiderManVoodoo1>() {}); } public void test() { Voodoo1.main(new String[0]); } } class SpiderManVoodoo1 { }
  • 160. 160/171 Caveats with Generics  Obtaining the type of a type parameter public final class Voodoo1 extends TestCase { public static void chill(final List<?> aListWithSomeType) { CommonTest.assertNotEqualAsExpected( aListWithSomeType, SpiderManVoodoo1.class); } public static void main(String... args) { Voodoo1.chill(new ArrayList<SpiderManVoodoo1>() {}); } public void test() { Voodoo1.main(new String[0]); } } class SpiderManVoodoo1 { }
  • 161. 161/171 Caveats with Generics  Obtaining the type of a type parameter public final class Voodoo1 extends TestCase { public static void chill(final List<?> aListWithSomeType) { CommonTest.assertNotEqualAsExpected( aListWithSomeType, SpiderManVoodoo1.class); } public static void main(String... args) { Voodoo1.chill(new ArrayList<SpiderManVoodoo1>() {}); } public void test() { Voodoo1.main(new String[0]); } } class SpiderManVoodoo1 { }
  • 162. 162/171 Caveats with Generics  Obtaining the type of a type parameter public final class Voodoo1 extends TestCase { public static void chill(final List<?> aListWithSomeType) { CommonTest.assertNotEqualAsExpected( aListWithSomeType, SpiderManVoodoo1.class); } public static void main(String... args) { Voodoo1.chill(new ArrayList<SpiderManVoodoo1>() {}); } public void test() { Voodoo1.main(new String[0]); } } class SpiderManVoodoo1 { } Anonymous/local class stores types information
  • 163. 163/171 Caveats with Generics  Obtaining the type of a type parameter public static void main(java.lang.String...); flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS Code: stack=2, locals=1, args_size=1 0: new #32 // class net/ptidej/generics/java/erasure/Voodoo1$1 3: dup 4: invokespecial #34 // Method net/ptidej/generics/java/erasure/Voodoo1$1."<init>":()V 7: invokestatic #35 // Method chill:(Ljava/util/List;)V 10: return LineNumberTable: line 38: 0 line 41: 10 LocalVariableTable: Start Length Slot Name Signature 0 11 0 args [Ljava/lang/String;
  • 164. 164/171 Caveats with Generics  Obtaining the type of a type parameter public static void main(java.lang.String...); flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS Code: stack=2, locals=1, args_size=1 0: new #32 // class net/ptidej/generics/java/erasure/Voodoo1$1 3: dup 4: invokespecial #34 // Method net/ptidej/generics/java/erasure/Voodoo1$1."<init>":()V 7: invokestatic #35 // Method chill:(Ljava/util/List;)V 10: return LineNumberTable: line 38: 0 line 41: 10 LocalVariableTable: Start Length Slot Name Signature 0 11 0 args [Ljava/lang/String;
  • 165. 165/171 Caveats with Generics  Obtaining the type of a type parameter // Compiled from Voodoo1.java (version 1.7 : 51.0, super bit) // Signature: Ljava/util/ArrayList<Lca/polymtl/ptidej/generics/java/erasure/SpiderManVoodoo1;>; class net.ptidej.generics.java.erasure.Voodoo1$1 extends java.util.ArrayList { ... // Method descriptor #11 ()V // Stack: 1, Locals: 1 Voodoo1$1(); 0 aload_0 [this] 1 invokespecial java.util.ArrayList() [13] 4 return Line numbers: [pc: 0, line: 38] [pc: 4, line: 1] Local variable table: [pc: 0, pc: 5] local: this index: 0 type: new ....java.erasure.Voodoo1(){} ... }
  • 166. 166/171 Outline  History  Problem  Special Case  General Definitions  Generics Definitions – Parametric Polymorphism – Other Bounded Parametric Polymorphisms  When to Use Generics  How to Use Generics  Caveats with Generics  Reflecting on Generics  Conclusion  Few References
  • 167. 167/171 Conclusion  Java generics “Implement generic algorithms that work on a collection of different types” —The Java Tutorials, Oracle
  • 168. 168/171 Conclusion  Scenario 1: you want to enforce type safety for containers and remove the need for typecasts when using these containers  Scenario 2: you want to build generic algorithms that work on several types of (possible unrelated) things
  • 169. 169/171 Conclusion  Easy to use in simple cases  Some caveats, though  Can be very tricky is corner cases – Use them sparingly and purposefully
  • 170. 170/171 Outline  History  Problem  Special Case  General Definitions  Generics Definitions – Parametric Polymorphism – Other Bounded Parametric Polymorphisms  When to Use Generics  How to Use Generics  Caveats with Generics  Reflecting on Generics  Conclusion  Few References
  • 171. 171/171 Outline  In no particular order – http://en.wikipedia.org/wiki/Generics_in_Java – http://www.angelikalanger.com/GenericsFAQ/FAQ Sections/TechnicalDetails.html#FAQ502 – http://www.uio.no/studier/emner/matnat/ifi/INF3110/h05/ lysark/Types.pdf – http://www.slideshare.net/SFilipp/java-puzzle-167104 – http://www.jquantlib.org/index.php/Using_TypeTokens_ to_retrieve_generic_parameters#Anonymous_classes – http://www.clear.rice.edu/comp310/JavaResources/ generics/ – http://gafter.blogspot.kr/2006/12/super-type-tokens.html