I was reading this article on Java Generics and there it is mentioned that the constructor for an ArrayList
looks somewhat like this:
class ArrayList<V> {
private V[] backingArray;
public ArrayList() {
backingArray = (V[]) new Object[DEFAULT_SIZE];
}
}
I was not able to understand how type erasure and type checking by the compiler happens as explained there. One point I got was that the type parameter is transformed to Object
type.
I would imagine it as (replacing all V
with Object
), but this definitely wrong.
class ArrayList<Object> {
private Object[] backingArray;
public ArrayList() {
backingArray = (Object[]) new Object[DEFAULT_SIZE];
}
}
How exactly is it transformed to Object
type but still retaining the type safety for V
?
when I have ArrayList<String>
and ArrayList<Integer>
are there two different classes for each? If not, where is the type information of String
and Integer
is stored?
- Erasure is a type of alteration in document. It can be classified as chemical erasure and physical erasure.
During the type erasure process, the Java compiler erases all type parameters and replaces each with its first bound if the type parameter is bounded, or Object if the type parameter is unbounded.
Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.
Type erasure is a process in which compiler replaces a generic parameter with actual class or bridge method. In type erasure, compiler ensures that no extra classes are created and there is no runtime overhead.
Your type erased version is not correct. The type parameter declaration is not erased to Object
but only it's usage is erased. More specifically:
ArrayList<V>
, it would be just ArrayList
.ArrayList<Integer>
will be replaced with ArrayList
.So, the correct erased version would be:
class ArrayList {
private Object[] backingArray;
public ArrayList() {
backingArray = (Object[]) new Object[DEFAULT_SIZE];
}
}
when I have ArrayList and ArrayList are there two different classes for each?
No, this is never the case. The compiler generates only one byte code representation of a generic type or method and maps all the instantiations of the generic type or method to the unique representation.
if not where the type information of String and Integer is stored?
When the compiler performs type-erasure, it removes all the type information, based on some pre-defined rules, occasionally adding what is called as bridge method, and adds all the necessary type casting required.
So, for example, the following usage of ArrayList<Integer>
and ArrayList<String>
:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
int value = list.get(0);
ArrayList<String> list2 = new ArrayList<String>();
list.add("A");
String value2 = list.get(0);
will be converted to somewhat like this:
ArrayList list = new ArrayList();
list.add(1);
int value = (Integer) list.get(0);
ArrayList list2 = new ArrayList();
list.add("A");
String value2 = (String) list.get(0);
Further Reading:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With