Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the logic of type erasure in java generics?

As far as I know, type generics happens in the following code:

public class Test {

    public void a(List<Object> list) {
    }

    public void a(List<String> list){
    }

    public void a(List<Integer> list){
    }

}

when the compiler compiles the code, the generic types will be erased so all the signatures are exactly same, which looks as follows:

public class Test {

    public void a(List list) {
    }

    public void a(List list){
    }

    public void a(List list){
    }

}

If this is the logic, then:

List<Object> objList = new ArrayList<>();
List<String> strList = new ArrayList<>();
objList = strList;  

is actually:

List objList = new ArrayList<>();
List strList = new ArrayList<>();
objList = strList; 

which is OK because both of the two lists are same type. However, In the above code, objList = strList will result an error.

Not quite sure what is the real logic. And what is more, the difference between List<?>, List(without any braces) and List< Object>

like image 584
Lake_Lagunita Avatar asked Dec 19 '25 20:12

Lake_Lagunita


1 Answers

To complement @Giorgi Tsiklauri's answer,

For the class below:

class Box<T> {
    T t;

    T getT() { return t; }

    void setT(T t) { this.t = t; }
}

because of type erasure, compiler compiles the class to:

class Box {
    Object t;

    Object getT() { return t; }

    void setT(Object t) { this.t = t; }
}

So, when you instantiate the Box<T> generic class with type argument Integer as follows:

Box<Integer> box = new Box<Integer>();
box.setT(10);
Integer t = box.getT();

the compiler knows that the Box<T> is instantiated with Integer because, at compile time, it sees that Box<Integer>. So, type casts are inserted by compiler. So the code above is compiled into:

Box box = new Box();
box.setT(10);
Integer t = (Integer) box.getT(); // compiler inserts type casts in lieu of us!

No matter how you instantiate the generic, the compiler doesn't create additional class files. If what actually happens at type erasure is replacement(replaces T with type argument such as Integer), the compiler have to create additional classes for Box for Integer, Box for Double etc — But that's not what actually happens at type erasure:

Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. — The Java™ Tutorials

Insert type casts if necessary to preserve type safety. — The Java™ Tutorials

Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead. — The Java™ Tutorials

like image 139
rosshjb Avatar answered Dec 22 '25 09:12

rosshjb



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!