Why does the following not compile? The compiler gives an error for the +
sign in the print line.
public class Test<T> {
HashMap<Integer,Integer> m = new HashMap<Integer, Integer>();
public static void main(String[] args) {
Integer zero1 = 0;
Integer zero2 = 0;
Test t = new Test();
t.m.put(1,zero1);
t.m.put(2,zero2);
System.out.println(t.m.get(1)+t.m.get(2)==t.m.get(2));
}
}
I understand type erasure, but m is a HashMap<Integer,Integer>
, it should not depend on the type <T>
at all. Why is the compiler rejecting this? Removing <T>
in the first line allows compiling, but I don't see why this shouldn't work as well.
Is this a compiler bug or is there any logic behind such behavior?
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.
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: Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded.
- Erasure is a type of alteration in document. It can be classified as chemical erasure and physical erasure.
It stores the data in (Key, Value) pairs, and you can access them by an index of another type (e.g. an Integer). One object is used as a key (index) to another object (value).
I don't have an explanation why, but the behavior does seem to be correct-by-definition.§4.8 "Raw Types" of the Java Language Specification explicitly states that:
The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3)
M
of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.
In your example, the raw type C is Test
(as opposed to Test<Object>
or Test<Integer>
or whatnot) and the non-static field M
is m
. As a result of the above rule, the type of t.m
is the raw type HashMap
, rather than HashMap<Integer, Integer>
, so the return-type of t.m.get(Object)
is Object
rather than Integer
.
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