Generics
Hsuan-Tien Lin
Department of CSIE, NTU
OOP Class, May 23, 2013
H.-T. Lin (NTU CSIE) Generics OOP 05/23/2013 0 / 16
How can we write a class for an Integer
set of arbitrary size?
How can we write a class for a String set of arbitrary size?
H.-T. Lin (NTU CSIE) Generics OOP 05/23/2013 2 / 16
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?
H.-T. Lin (NTU CSIE) Generics OOP 05/23/2013 4 / 16
Motivation of Generics (1/3)
1 c l a s s S t r i n g A r r a y {
2 p r i v a t e S t r i n g [ ] myarr ;
3 p u b l i c S t r i n g A r r a y (i n t l e n ) { myarr = new S t r i n g [ l e n ] ; }
4 p u b l i c S t r i n g g e t (i n t n ) { r e t u r n myarr [ n ] ; }
5 p u b l i c v o i d s e t (i n t n , S t r i n g s ) { myarr [ n ] = s ; }
6 p u b l i c v o i d s h o w A l l ( ) {
7 f o r(i n t i = 0 ; i <myarr . l e n g t h ; i ++)
8 System . o u t . p r i n t l n ( myarr [ i ] ) ;
9 }
10 }
11 c l a s s P r o f e s s o r A r r a y {
12 p r i v a t e P r o f e s s o r [ ] myarr ;
13 p u b l i c P r o f e s s o r A r r a y (i n t l e n ) { myarr = new P r o f e s s o r [ l e n ] ; }
14 p u b l i c P r o f e s s o r g e t (i n t n ) { r e t u r n myarr [ n ] ; }
15 p u b l i c v o i d s e t (i n t n , P r o f e s s o r p ) { myarr [ n ] = p ; }
16 p u b l i c v o i d s h o w A l l ( ) {
17 f o r(i n t i = 0 ; i <myarr . l e n g t h ; i ++)
18 System . o u t . p r i n t l n ( myarr [ i ] ) ;
19 }
20 }
Can we avoid writing the same boring things again and again?
Motivation of Generics (2/3)
1 c l a s s O b j e c t A r r a y {
2 p r i v a t e O b j e c t [ ] myarr ;
3 p u b l i c O b j e c t A r r a y (i n t l e n ) { myarr = new O b j e c t [ l e n ] ; }
4 p r o t e c t e d O b j e c t g e t (i n t n ) { r e t u r n myarr [ n ] ; }
5 p r o t e c t e d v o i d s e t (i n t n , O b j e c t o ) { myarr [ n ] = o ; }
6 p u b l i c v o i d s h o w A l l ( ) {
7 f o r(i n t i = 0 ; i <myarr . l e n g t h ; i ++)
8 System . o u t . p r i n t l n ( myarr [ i ] ) ;
9 }
10 }
11
12 c l a s s S t r i n g A r r a y extends O b j e c t A r r a y {
13 p u b l i c S t r i n g A r r a y (i n t l e n ) { super( l e n ) ; }
14 p u b l i c S t r i n g g e t (i n t n ) { r e t u r n ( S t r i n g )super. g e t ( n ) ; }
15 p u b l i c v o i d s e t (i n t n , S t r i n g s ) { super. s e t ( n , s ) ; }
16 }
Yes, by inheritance and polynormphism—everything is an Object
H.-T. Lin (NTU CSIE) Generics OOP 05/23/2013 6 / 16
Motivation of Generics (3/3)
1 c l a s s ANYArray {
2 p r i v a t e ANY [ ] myarr ;
3 p u b l i c ANYArray (i n t l e n ) { myarr = new ANY [ l e n ] ; }
4 p r o t e c t e d ANY g e t (i n t n ) { r e t u r n myarr [ n ] ; }
5 p r o t e c t e d v o i d s e t (i n t n , ANY o ) { myarr [ n ] = o ; }
6 p u b l i c v o i d s h o w A l l ( ) {
7 f o r(i n t i = 0 ; i <myarr . l e n g t h ; i ++)
8 System . o u t . p r i n t l n ( myarr [ i ] ) ;
9 }
10 }
Yes, by identifying the common parts, and then replacing sed ’s/ANY/String/’ ANYArray.java >
StringArray.java
C++ Solution (roughly)
1 t e m p l a t e <c l a s s ANY>
2 c l a s s A r r a y {
3 p r i v a t e ANY [ ] myarr ;
4 p u b l i c A r r a y (i n t l e n ) { myarr = new ANY [ l e n ] ; }
5 p r o t e c t e d ANY g e t (i n t n ) { r e t u r n myarr [ n ] ; }
6 p r o t e c t e d v o i d s e t (i n t n , ANY o ) { myarr [ n ] = o ; }
7 p u b l i c v o i d s h o w A l l ( ) {
8 f o r(i n t i = 0 ; i <myarr . l e n g t h ; i ++)
9 System . o u t . p r i n t l n ( myarr [ i ] ) ;
10 }
11 }
12
13 {
14 Array < S t r i n g > s a r r ( 5 ) ;
15 s a r r . s e t ( 3 , " l a l a l a " ) ;
16 }
basically, the step sed ’s/ANY/String/’ ANYArray.cpp >
StringArray.cpp done by compiler
code automatically duplicates during complication as you use Array<String>, Array<Integer>, Array<Double>, ...
H.-T. Lin (NTU CSIE) Generics OOP 05/23/2013 8 / 16
Java Solution (roughly)
1 c l a s s Array <ANY> {
2 p r i v a t e ANY [ ] myarr ;
3 p u b l i c A r r a y (i n t l e n ) { myarr = (ANY [ ] ) (new O b j e c t [ l e n ] ) ; }
4 p r o t e c t e d ANY g e t (i n t n ) { r e t u r n myarr [ n ] ; }
5 p r o t e c t e d v o i d s e t (i n t n , ANY o ) { myarr [ n ] = o ; }
6 p u b l i c v o i d s h o w A l l ( ) {
7 f o r(i n t i = 0 ; i <myarr . l e n g t h ; i ++)
8 System . o u t . p r i n t l n ( myarr [ i ] ) ;
9 }
10 }
11
12 {
13 Array < S t r i n g > s a r r ( 5 ) ;
14 s a r r . s e t ( 3 , " l a l a l a " ) ;
15 }
the ANY → Object step is automatically done by compiler: a true
one-class solution
How does duplicating solution compare with one-class solution?
H.-T. Lin (NTU CSIE) Generics OOP 05/23/2013 10 / 16
How can we write one class for arbitrary
sets of arbitrary size while keeping type
information?
Should StringSet extend ObjectSet?
H.-T. Lin (NTU CSIE) Generics OOP 05/23/2013 12 / 16
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 information erased after compilation
Type Erasure: Mystery 1
1 c l a s s Set <T> {
2 Set ( ) {
3 T [ ] a r r = new T [ 1 0 ] ;
4 a r r [ 0 ] = new T ( ) ;
5 }
6 }
cannot new with an “undetermined type” T (no T in runtime)
H.-T. Lin (NTU CSIE) Generics OOP 05/23/2013 14 / 16
Type Erasure: Mystery 2
1 c l a s s Set <T> {
2 }
3 p u b l i c c l a s s Fun {
4 p u b l i c s t a t i c v o i d main ( S t r i n g [ ] argv ) {
5 Set < S t r i n g > [ ] a r r = new Set < S t r i n g > [ 2 0 ] ;
6 a r r [ 0 ] . addElement (new I n t e g e r ( 3 ) ) ;
7 }
8 }
cannot create generic array (after type erasure, no type
guarantee)
Use of Generics: Java Collection Framework
interfaces: Collection (Set, List) and Map
abstract classes: AbstractCollection (AbstractSet, AbstractList) and AbstractMap
concrete classes: HashSet, ArrayList, HashMap
H.-T. Lin (NTU CSIE) Generics OOP 05/23/2013 16 / 16