Generics
Hsuan-Tien Lin
Deptartment of CSIE, NTU
OOP Class, May 19, 2009
How can we write a class for an Integer set of arbitrary size?
class IntegerSet{
Integer[] arr;
int count;
IntegerSet(int len){ arr = new Integer[len]; } void add(Integer i){
if (count < arr.length){arr[count] = i; count++; } }
void removeLast(){ arr[count] = null; count--; }
How can we write a class a String set of arbitrary size?
class StringSet{
String[] arr;
int count;
StringSet(int len){ arr = new String[len]; } void add(String i){
if (count < arr.length){arr[count] = i; count++; } }
void removeLast(){ arr[count] = null; count--; } }
How can we write classes for Inte-
ger/String/Double/Professor sets of arbi-
trary size?
How can we write one class for arbitrary sets of arbitrary size?
class PowerfulSet{
String[] sarr; Integer[] iarr; Professor[] parr;
int scount, icount, pcount;
PowerfulSet(int len){ sarr = new String[len]; iarr ...;
parr....}
void add(String s){ ... } void add(Integer i){ ...}
}
class ObjectSet{
Object[] arr; int count;
ObjectSet(int len){ arr = new Object[len]; } void add(Object o){ ... }
}
How does duplicating solution compare
with one-class solution?
How can we write one class for arbitrary sets of arbitrary size while keeping type information?
class StringSet extends ObjectSet{
StringSet(int len){ super(len); } void add(String s){ super.add(s); }
String get(int i){ return (String)super.get(i); } }
class Set<T>{
Object[] arr;
int count;
Set(int len){ arr = new Object[len]; } void add(T i){if (count < arr.length) {arr[count] = i; count++; }}
T get(int pos){ return (T)arr[pos]; } }
Should StringSet extend ObjectSet?
class StringSet extends ObjectSet{
StringSet(int len){ super(len); } void add(String s){ super.add(s); }
String get(int i){ return (String)super.get(i); } }
Java Solution: Generics (since 1.4)
no manual duplicating (as opposed to old languages): save coding efforts
no automatic duplicating (as opposed to C++): save code size and re-compiling efforts
check type information very strictly by compiler (as opposed to single-object polymorphism): ensure type safety in JVM
Note: type informationerased after compilation
AbstractCollection.containsAll(...)
Go Check the Source Code!
AbstractCollection.addAll(...)
Go Check the Source Code!
AbstractCollection.toArray(...)
Go Check the Source Code!
More on Type Erasure
1 A r r a y L i s t < S t r i n g > l 1 = new A r r a y L i s t < S t r i n g > ( ) ;
2 A r r a y L i s t < I n t e g e r > l 2 = new A r r a y L i s t < I n t e g e r > ( ) ;
3 System . o u t . p r i n t l n ( l 1 . g e t C l a s s ( ) == l 2 . g e t C l a s s ( ) ) ;
4 System . o u t . p r i n t l n ( l 1 i n s t a n c e o f C o l l e c t i o n < S t r i n g > ) ;
More on Type Safety
1 A r r a y L i s t < S t r i n g > [ ] l s 1 = new A r r a y L i s t < S t r i n g > [ 1 0 ] ;
2 A r r a y L i s t < ? > [ ] l s 2 = new A r r a y L i s t < ? > [ 1 0 ] ;
3 A r r a y L i s t < S t r i n g > [ ] l s 3 = new A r r a y L i s t < ? > [ 1 0 ] ;
Why Is This Illegal?
1 <T> T [ ] makeArray ( T t , i n t l e n ) {
2 r e t u r n new T [ l e n ] ;
3 }