Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doesn't type parameter play any role?

Tags:

java

generics

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 ?

like image 235
NaneV Avatar asked Nov 08 '22 12:11

NaneV


1 Answers

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
like image 80
vsminkov Avatar answered Nov 14 '22 21:11

vsminkov