问题
When comes to bridge method, i do know that java compiler will add them if there's a need so that overriding can be done properly by the subclass (after reading SCJP by mughal and angelikalanger website). But this is a bit confusing as per below:
Before erasure:
class x <T> {
void set(T t){}
}
class y <E> extends x {
void set(E e) {} // name clash here
}
class z<E> extends x {
void set(Object y) {} // no name clash here
}
class z1<E> extends x<T> {
void set(Object y) {} // name clash here
}
after erasure:
class x {
void set (Object t) {}
}
I understand the name clash for class y but why there is no name clash for class z? Also there is a name clash for class z1? Puzzling
回答1:
class y <E> extends x {
void set(E e) {} // name clash here
}
Here name clash occurs because E is not a subclass of T. So you cannot override the set method this way.see the explanation for z1 to understand better. For class y to work, you must have
class y <E> extends x<E> {
void set(E e) {}
}
Next:
class z<E> extends x {
void set(Object y) {} // no name clash here
}
Here there is no name clash because in the class X, set method gets interpreted as
void set(java.lang.Object)
and in class z also the parameter of set is java.lang.Object.so no clash.
Next:
class z1<E> extends x<T> {
void set(Object y) {} // name clash here
}
Again here name clash occurs because you have to have as parameter of set whatever type parameter you give to x. here, you pass to x type parameter T, but you have parameter of set method as java.lang.Object. hence name clash.
For z to work you must have:
class z1<E> extends x<Object> {
void set(Object y) {}
}
回答2:
As you say, after erasure the set method takes an Object. z
extends the non-generic, after erasure x
来源:https://stackoverflow.com/questions/6557586/java-generics-bridge-method