当谈到bridge方法时,我知道java编译器会在需要时添加它们,以便子类可以正确地完成覆盖(在阅读了mughal和angelikalanger网站的SCJP之后)。但这有点令人困惑,如下所示:
在删除之前:
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
}
擦除后:
class x {
void set (Object t) {}
}
我理解y类的名称冲突,但为什么z类没有名称冲突? 类z1也有名称冲突?令人费解的
答案 0 :(得分:2)
class y <E> extends x {
void set(E e) {} // name clash here
}
这里发生名称冲突,因为E不是T的子类。所以你不能用这种方式覆盖set方法。请参阅z1的解释以便更好地理解。 要使y级工作,你必须
class y <E> extends x<E> {
void set(E e) {}
}
下一步:
class z<E> extends x {
void set(Object y) {} // no name clash here
}
这里没有名称冲突,因为在类X中,set方法被解释为
void set(java.lang.Object)
并且在类z中,set的参数也是java.lang.Object.so no clash。
下一步:
class z1<E> extends x<T> {
void set(Object y) {} // name clash here
}
此处发生名称冲突,因为您必须具有设置为x提供的任何类型参数的参数。在这里,您传递给x类型参数T,但您将set方法的参数作为java.lang.Object。因此命名冲突。
要使z工作,你必须:
class z1<E> extends x<Object> {
void set(Object y) {}
}
答案 1 :(得分:1)
正如你所说,在擦除之后set方法接受一个Object。在删除z
x
扩展了非泛型