Suppose I have a generic class Parcel and a generic method deliver shown in the below code. The method prints and returns x which is assigned a type parameter Integer inside the method.
public class Parcel<T> {
public <X> X deliver(){
X x = (X) new Integer(100);
System.out.println(x);
return x;
}
}
Inside the main I call the method deliver by passing a type parameter Parcel. However it still prints 100.
public static void main(String args[]) {
Parcel<String> parcel = new Parcel<>();
System.out.println(parcel.<Parcel> deliver());
}
This follows that the type argument Parcel passed in the print line doesn't play any role, and I expected an exception here. How does it work ?
What you observe is called type erasure. Generic parameters are used by compiler to ensure type correctness and does not present in run-time.
Generally speaking nothing stops you from doing this trick:
List<Integer> list = new ArrayList<>();
list.append(""); // produces compiler error
// just drop that "useless" generic argument
List erased = (List) list;
erased.append(""); // works fine
EDIT
Actually my original answer occasionally was for this Parcel
implementation
public class Parcel<T> {
public T deliver(){
T x = (T) new Integer(100);
System.out.println(x);
return x;
}
}
But the key idea is the same for <X> X deliver()
:
Object parcel = parcel.<Parcel> deliver(); // erased, works ok
Parcel parcel = parcel.<Parcel> deliver(); // java.lang.ClassCastException
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