Java generics at run time
Madhavan Mukund
[Link]
Programming Concepts using Java
Week 5
Erasure of generic information
Type erasure — Java does not keep record all versions of LinkedList<T> as
separate types
Cannot write
if (s instanceof LinkedList<String>){ ... }
Madhavan Mukund Java generics at run time Programming Concepts using Java 2/7
Erasure of generic information
Type erasure — Java does not keep record all versions of LinkedList<T> as
separate types
Cannot write
if (s instanceof LinkedList<String>){ ... }
At run time, all type variables are promoted to Object
LinkedList<T> becomes LinkedList<Object>
Madhavan Mukund Java generics at run time Programming Concepts using Java 2/7
Erasure of generic information
Type erasure — Java does not keep record all versions of LinkedList<T> as
separate types
Cannot write
if (s instanceof LinkedList<String>){ ... }
At run time, all type variables are promoted to Object
LinkedList<T> becomes LinkedList<Object>
Or, the upper bound, if one is available
LinkedList<? extends Shape> becomes LinkedList<Shape>
Madhavan Mukund Java generics at run time Programming Concepts using Java 2/7
Erasure of generic information
Type erasure — Java does not keep record all versions of LinkedList<T> as
separate types
Cannot write
if (s instanceof LinkedList<String>){ ... }
At run time, all type variables are promoted to Object
LinkedList<T> becomes LinkedList<Object>
Or, the upper bound, if one is available
LinkedList<? extends Shape> becomes LinkedList<Shape>
Since no information about T is preserved, cannot use T in expressions like
if (o instanceof T) {...}
Madhavan Mukund Java generics at run time Programming Concepts using Java 2/7
Erasure and overloading
Type erasure means the comparison in following code fragment returns True
o1 = new LinkedList<Employee>();
o2 = new LinkedList<Date>();
if ([Link]() == [Link]){
// True, so this block is executed
}
Madhavan Mukund Java generics at run time Programming Concepts using Java 3/7
Erasure and overloading
Type erasure means the comparison in following code fragment returns True
o1 = new LinkedList<Employee>();
o2 = new LinkedList<Date>();
if ([Link]() == [Link]){
// True, so this block is executed
}
As a consequence the following overloading is illegal
public class Example {
public void printlist(LinkedList<String> strList) { }
public void printlist(LinkedList<Date> dateList) { }
}
Madhavan Mukund Java generics at run time Programming Concepts using Java 3/7
Erasure and overloading
Type erasure means the comparison in following code fragment returns True
o1 = new LinkedList<Employee>();
o2 = new LinkedList<Date>();
if ([Link]() == [Link]){
// True, so this block is executed
}
As a consequence the following overloading is illegal
public class Example {
public void printlist(LinkedList<String> strList) { }
public void printlist(LinkedList<Date> dateList) { }
}
Both functions have the same signature after type erasure
Madhavan Mukund Java generics at run time Programming Concepts using Java 3/7
Arrays and generics
Recall the covariance problem for arrays
If S extends T then S[] extends T[]
Madhavan Mukund Java generics at run time Programming Concepts using Java 4/7
Arrays and generics
Recall the covariance problem for arrays
If S extends T then S[] extends T[]
Can lead to run time type errors
ETicket[] elecarr = new ETicket[10];
Ticket[] ticketarr = elecarr; // OK. ETicket[] is a subtype of Ticket[]
...
ticketarr[5] = new Ticket(); // Not OK. ticketarr[5] refers to an ETicket!
Madhavan Mukund Java generics at run time Programming Concepts using Java 4/7
Arrays and generics
Recall the covariance problem for arrays
If S extends T then S[] extends T[]
Can lead to run time type errors
ETicket[] elecarr = new ETicket[10];
Ticket[] ticketarr = elecarr; // OK. ETicket[] is a subtype of Ticket[]
...
ticketarr[5] = new Ticket(); // Not OK. ticketarr[5] refers to an ETicket!
To avoid similar problems, can declare a generic array, but cannot instantiate it
T[] newarray; // OK
newarray = new T[100]; // Cannot create!
Madhavan Mukund Java generics at run time Programming Concepts using Java 4/7
Arrays and generics
Recall the covariance problem for arrays
If S extends T then S[] extends T[]
Can lead to run time type errors
ETicket[] elecarr = new ETicket[10];
Ticket[] ticketarr = elecarr; // OK. ETicket[] is a subtype of Ticket[]
...
ticketarr[5] = new Ticket(); // Not OK. ticketarr[5] refers to an ETicket!
To avoid similar problems, can declare a generic array, but cannot instantiate it
T[] newarray; // OK
newarray = new T[100]; // Cannot create!
An ugly workaround . . .
T[] newarray;
newarray = (T[]) new Object[100];
Madhavan Mukund Java generics at run time Programming Concepts using Java 4/7
Arrays and generics
Recall the covariance problem for arrays
If S extends T then S[] extends T[]
Can lead to run time type errors
ETicket[] elecarr = new ETicket[10];
Ticket[] ticketarr = elecarr; // OK. ETicket[] is a subtype of Ticket[]
...
ticketarr[5] = new Ticket(); // Not OK. ticketarr[5] refers to an ETicket!
To avoid similar problems, can declare a generic array, but cannot instantiate it
T[] newarray; // OK
newarray = new T[100]; // Cannot create!
An ugly workaround . . . generates a compiler warning but works!
T[] newarray;
newarray = (T[]) new Object[100];
Madhavan Mukund Java generics at run time Programming Concepts using Java 4/7
Wrapper classes
Type erasure — at run time, all type variables are promoted to Object
LinkedList<T> becomes LinkedList<Object>
Madhavan Mukund Java generics at run time Programming Concepts using Java 5/7
Wrapper classes
Type erasure — at run time, all type variables are promoted to Object
LinkedList<T> becomes LinkedList<Object>
Basic types int, float, . . . are not compatible with Object
Madhavan Mukund Java generics at run time Programming Concepts using Java 5/7
Wrapper classes
Type erasure — at run time, all type variables are promoted to Object
LinkedList<T> becomes LinkedList<Object>
Basic types int, float, . . . are not compatible with Object
Cannot use basic type in place of a generic type variable T
Cannot instantiate LinkedList<T> as LinkedList<int>, LinkedList<double>, . . .
Madhavan Mukund Java generics at run time Programming Concepts using Java 5/7
Wrapper classes
Type erasure — at run time, all type variables are promoted to Object
LinkedList<T> becomes LinkedList<Object>
Basic types int, float, . . . are not compatible with Object
Cannot use basic type in place of a generic type variable T
Cannot instantiate LinkedList<T> as LinkedList<int>, LinkedList<double>, . . .
Wrapper class for each basic type:
Basic type Wrapper Class Basic type Wrapper Class
byte Byte float Float
short Short double Double
int Integer boolean Boolean
long Long char Character
Madhavan Mukund Java generics at run time Programming Concepts using Java 5/7
Wrapper classes
Type erasure — at run time, all type variables are promoted to Object
LinkedList<T> becomes LinkedList<Object>
Basic types int, float, . . . are not compatible with Object
Cannot use basic type in place of a generic type variable T
Cannot instantiate LinkedList<T> as LinkedList<int>, LinkedList<double>, . . .
Wrapper class for each basic type:
Basic type Wrapper Class Basic type Wrapper Class
byte Byte float Float
short Short double Double
int Integer boolean Boolean
long Long char Character
All wrapper classes other than Boolean, Character extend the class Number
Madhavan Mukund Java generics at run time Programming Concepts using Java 5/7
Wrapper classes
Converting from basic type to wrapper class and back
int x = 5;
Integer myx = Integer(x);
int y = [Link]();
Madhavan Mukund Java generics at run time Programming Concepts using Java 6/7
Wrapper classes
Converting from basic type to wrapper class and back
int x = 5;
Integer myx = Integer(x);
int y = [Link]();
Similarly, byteValue(), doubleValue(), . . .
Madhavan Mukund Java generics at run time Programming Concepts using Java 6/7
Wrapper classes
Converting from basic type to wrapper class and back
int x = 5;
Integer myx = Integer(x);
int y = [Link]();
Similarly, byteValue(), doubleValue(), . . .
Autoboxing — implicit conversion between base types and wrapper types
int x = 5;
Integer myx = x;
int y = myx;
Madhavan Mukund Java generics at run time Programming Concepts using Java 6/7
Wrapper classes
Converting from basic type to wrapper class and back
int x = 5;
Integer myx = Integer(x);
int y = [Link]();
Similarly, byteValue(), doubleValue(), . . .
Autoboxing — implicit conversion between base types and wrapper types
int x = 5;
Integer myx = x;
int y = myx;
Use wrapper types in generic data structures
Madhavan Mukund Java generics at run time Programming Concepts using Java 6/7
Summary
Java generics come with some restrictions
Information about type variables is erased at runtime
LinkedList<T> becomes LinkedList<Object>
LinkedList<? extends Shape> becomes LinkedList<Shape>
Limits the use reflection on generic types — cannot write
if (o instanceof LinkedList<String>) {...}
if (o instanceof T) {...}
Cannot overload function signatures using instantiation of generic types
Cannot instantiate arrays of generic type
Need to box built-in types using wrapper types
Madhavan Mukund Java generics at run time Programming Concepts using Java 7/7