What is the concept of erasure in generics in Java?
Why use Generices
In a nutshell, generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Much like the more familiar formal parameters used in method declarations, type parameters provide a way for you to re-use the same code with different inputs. The difference is that the inputs to formal parameters are values, while the inputs to type parameters are types. ode that uses generics has many benefits over non-generic code:
What is Type Erasure
Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to:
[N.B.]-What is bridge method? To shortly, In the case of a parameterized interface such as Comparable
, this may cause additional methods to be inserted by the compiler; these additional methods are called bridges.
How Erasure Works
The erasure of a type is defined as follows: drop all type parameters from parameterized types, and replace any type variable with the erasure of its bound, or with Object if it has no bound, or with the erasure of the leftmost bound if it has multiple bounds. Here are some examples:
List
, List
, and List>
is List
.List[]
is List[]
.List
is itself, similarly for any raw type.Integer
is itself, similarly for any type without type parameters.T
in the definition of asList
is Object
, because T
has no bound.T
in the definition of max
is Comparable
, because T
has bound Comparable super T>
.T
in the final definition of max
is Object
, because
T
has bound Object
& Comparable
and we take the erasure of the leftmost bound.Need to be careful when use generics
In Java, two distinct methods cannot have the same signature. Since generics are implemented by erasure, it also follows that two distinct methods cannot have signatures with the same erasure. A class cannot overload two methods whose signatures have the same erasure, and a class cannot implement two interfaces that have the same erasure.
class Overloaded2 {
// compile-time error, cannot overload two methods with same erasure
public static boolean allZero(List ints) {
for (int i : ints) if (i != 0) return false;
return true;
}
public static boolean allZero(List strings) {
for (String s : strings) if (s.length() != 0) return false;
return true;
}
}
We intend this code to work as follows:
assert allZero(Arrays.asList(0,0,0));
assert allZero(Arrays.asList("","",""));
However, in this case the erasures of the signatures of both methods are identical:
boolean allZero(List)
Therefore, a name clash is reported at compile time. It is not possible to give both methods the same name and try to distinguish between them by overloading, because after erasure it is impossible to distinguish one method call from the other.
Hopefully, Reader will enjoy :)