java generics for dummies
DESCRIPTION
A quick & dirty presentation from early 2005 I held for a company after I was provoked by how Generics had been implemented in Java..TRANSCRIPT
![Page 1: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/1.jpg)
Generics for Dummies
...or how to shoot an elephant from five feet, and miss!
Knut Mork – 22.2.2005
![Page 2: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/2.jpg)
"The increase in complexity is increasing,
in part because of the natural, inevitable trend of technology
to put together ever-more powerful solutions
to problems we never realized we had.”
Donald Norman
![Page 3: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/3.jpg)
Traditional example
List myIntList = new ArrayList();
myIntList.add(new Integer(0));
Integer x = (Integer) myIntList.iterator().next();
Same example using generics
List<Integer> myIntList = new ArrayList<Integer>();
myIntList.add(new Integer(0));
Integer x = myIntList.iterator().next();
![Page 4: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/4.jpg)
Excerpt from java.util:
public interface List<E> {
void add(E x);
Iterator<E> iterator();
}
public interface Iterator<E> {
E next();
boolean hasNext();
}
![Page 5: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/5.jpg)
• What ?– To abstract over types
• Why ?– Safer code, eliminate run-time checks– Strong typing (not loose info)– Remove (visible) down-casting– Reduce awful, but necessary javadoc comments– Increase the indend of your code/interface– Others ?
• Where ?– Collections, reflection (but problems with impl), others ?
• When ?– Introduced in Java 1.5
![Page 6: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/6.jpg)
No more casting ?
Basket<Fruit> basket = new Basket<Fruit>();
basket.addElement(new Apple());
Apple apple = (Apple) basket.pickElement();
![Page 7: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/7.jpg)
Simple, right?
... wrong!
![Page 8: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/8.jpg)
“Any fool can write code that a computer can understand.
Good programmers write code that humans can understand.”
Martin Fowler
![Page 9: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/9.jpg)
Real example from java.util.Collections:
public static <T extends Object &
Comparable<? super T>> max(Collection<? extends T> coll)
public static Object max(Collection coll)
JDK 1.5
JDK 1.4
![Page 10: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/10.jpg)
Example - subtyping
List<String> ls = new ArrayList<String>();
List<Object> lo = ls;
lo.add(new Object());
String s = ls.get(0);
![Page 11: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/11.jpg)
Example - subtyping
List<String> ls = new ArrayList<String>();
List<Object> lo = ls; // compile-time error
lo.add(new Object());
String s = ls.get(0);
![Page 12: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/12.jpg)
Traditional example2
void printCollection(Collection c) {Iterator i = c.iterator();for(k = 0; k < c.size(); k++) {System.out.println(i.next());}}
Same example2 using generics
void printCollection(Collection<Object> c) {for(Object e : c) {System.out.println(e);}}
![Page 13: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/13.jpg)
Traditional example2
void printCollection(Collection c) {Iterator i = c.iterator();for(k = 0; k < c.size(); k++) {System.out.println(i.next());}}
Same example2 using generics
void printCollection(Collection<?> c) {for(Object e : c) {System.out.println(e);}}
![Page 14: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/14.jpg)
But, on the other hand...
Collection<?> c = new ArrayList<String>();
c.add(new Object()); // compile-time error
![Page 15: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/15.jpg)
It gets worse...
”The single biggest enemy of reliability
(and perhaps software quality in general)
is complexity.”
Bertrand Meyer
![Page 16: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/16.jpg)
Bounded Wildcards
public void eatAll (List<Fruit> fruites) {for (Fruit f: fruites) {
f.eat(this);}
}
public void eatAll(List<? extends Fruit> fruites) {...
}
![Page 17: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/17.jpg)
Bounded Wildcards
public void addBanana(List<? extends Fruit> fruites) {fruites.add(0, new Banana());
}
![Page 18: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/18.jpg)
Bounded Wildcards
public void addBanana(List<? extends Fruit> fruites) {fruites.add(0, new Banana()); // compile-time error
}
![Page 19: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/19.jpg)
...a lot worse...
"Once a satisfactory product has been achieved,
further change may be counterproductive,
especially if the product is successful.
You have to know when to stop.”
Donald Norman
![Page 20: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/20.jpg)
Example 3
static void fromArrayToCollection(Object[] a, Collection c) {for (Object o : a) { c.add(o);}
}
![Page 21: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/21.jpg)
Example 3
static void fromArrayToCollection(Object[] a, Collection c) {for (Object o : a) { c.add(o);}
}
Generic version:
static void fromArrayToCollection(Object[] a, Collection<?> c) {for (Object o : a) { c.add(o);}
}
![Page 22: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/22.jpg)
Example 3
static void fromArrayToCollection(Object[] a, Collection c) {for (Object o : a) { c.add(o);}
}
Generic version:
static void fromArrayToCollection(Object[] a, Collection<?> c) {for (Object o : a) { c.add(o); // compile-time error}
}
![Page 23: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/23.jpg)
Example 3
static void fromArrayToCollection(Object[] a, Collection c) {for (Object o : a) { c.add(o);}
}
Generic working version:
static <T> void fromArrayToCollection(T[] a, Collection<T> c) {for (T o : a) { c.add(o);}
}
![Page 24: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/24.jpg)
”Under the hood”
”When simple things need instruction,
it is a certain sign of poor design.”
Donald Norman
![Page 25: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/25.jpg)
Traditional example
List myIntList = new ArrayList();
myIntList.add(new Integer(0));
Integer x = (Integer) myIntList.iterator().next();
Same example using generics
List<Integer> myIntList = new ArrayList<Integer>();
myIntList.add(new Integer(0));
Integer x = myIntList.iterator().next();
![Page 26: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/26.jpg)
List <String> l1 = new ArrayList<String>();List<Integer> l2 = new ArrayList<Integer>();System.out.println(l1.getClass() == l2.getClass());
Output result ?
![Page 27: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/27.jpg)
Collection cs = new ArrayList<String>();if(cs instanceof Collection<String>) {...}
Output result ?
![Page 28: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/28.jpg)
Legacy code interoperability
"You must not give the world what it asks for,
but what it needs.”
Edsger Dijkstra
![Page 29: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/29.jpg)
Using legacy code in 1.5
List fruitList1 = new ArrayList<Fruit>(); fruitList1.add(new Apple()); // warning
List fruitList2 = new ArrayList();fruitList2 = juggle(fruitList2); // warning
List<Fruit> fruitList3 = new ArrayList<Fruit>();fruitList3 = eat(fruitList3); // warning
public List eat(List fruits) {...}public List<Fruit> juggle(List<Fruit> fruits) {...}
![Page 30: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/30.jpg)
Using legacy code in 1.5
public String loophole(Integer x) {List<String> ys = new ArrayList<String>();List xs = ys;xs.add(x); // compile-time unchecked warningreturn ys.iterator().next();
}
![Page 31: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/31.jpg)
Example of warnings given:
Unsafe type operation:
Should not assign expression of raw type List to type List<Foo>. References to generic type List<E> should be parameterized.
Unsafe type operation:
The method bar(List<Foo>) in the type SimpleExample should not be applied for the arguments (List). References to generic types should be parameterized.
![Page 32: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/32.jpg)
...and even worse...
"Once a satisfactory product has been achieved,
further change may be counterproductive,
especially if the product is successful.
You have to know when to stop.”
Donald Norman
![Page 33: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/33.jpg)
• A type parameter cannot be referenced in a static context
• Runtime type check with instanceof and casting on generic types have no meaning
• Arrays of generic types are not permitted
• For overloading, it is not enough to use wildcards for formal parameter types
• Generic classes can be extended– The subclass provides the actual type parameters for the superclass
• For overriding, the return type of the method in the subclass can now be identical or a subtype of the return type of the method in the superclass
• A generic class cannot be a subclass of Throwable
• Type parameters are allowed in the throws clause, but not for the parameter of the catch block
• Varargs with a parameterized type are not legal
![Page 34: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/34.jpg)
Introduction of characters with new special meaning
<, > ? T, E, ...
super &
”Programs must be written for people to read, and only incidentally for machines to execute.”
Abelson and Sussman
![Page 35: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/35.jpg)
Which ones will compile ?
a) Basket b = new Basket();
b) Basket b1 = new Basket<Fruit>();
c) Basket<Fruit> b2 = new Basket<Fruit>();
d) Basket<Apple> b3 = new Basket<Fruit>();
e) Basket<Fruit> b4 = new Basket<Apple>();
f) Basket<?> b5 = new Basket<Apple>();
g) Basket<Apple> b6 = new Basket<?>();
![Page 36: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/36.jpg)
Thoughts and comments
Anyone ?
Is this a good thing or not ? Is it an important feature of the language ?
What if this was included in the first version ?Would the design be different/easier ?Would users use it differently ?
When should we use it ? If we should, that is!
Why can’t we find other good examples, but the collection ones ?
![Page 37: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/37.jpg)
Still interested ?
• Intro paper:http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
• Angelika’s F.A.Q. http://www.langer.camelot.de/GenericsFAQ/JavaGenericsFAQ.html
![Page 38: Java Generics for Dummies](https://reader036.vdocuments.mx/reader036/viewer/2022081421/55620754d8b42a7d028b46fc/html5/thumbnails/38.jpg)
”There are two ways of constructing a software design:
One way is to make it so simple
that there are obviously no deficiencies,
and the other way is to make it so complicated
that there are no obvious deficiencies.
The first method is far more difficult.”
C. A. R. Hoare