Java 两种方法具有相同的擦除
我读过类似的问题,知道一般的擦除会在同一个类中导致这个错误。但我不明白为什么下面的代码不起作用 我设计了一些例子。发现很多事情让人困惑Java 两种方法具有相同的擦除,java,generics,overriding,Java,Generics,Overriding,我读过类似的问题,知道一般的擦除会在同一个类中导致这个错误。但我不明白为什么下面的代码不起作用 我设计了一些例子。发现很多事情让人困惑 public static class Father<S> { public void foo(Set<String> s) {...} public void bar(S s) {...} public void baz(String s) {...} } public static class Son
public static class Father<S> {
public void foo(Set<String> s) {...}
public void bar(S s) {...}
public void baz(String s) {...}
}
public static class Son<E> extends Father {
public void foo(Set<String> s) {...} **// error**
public void bar(E e) {...} **// error**
// public void bar(Object e) {...} // This works
public void baz(String s) {...}
}
public static class Daughter<E> extends Father<T> {
public void foo(Set<String> s) {...} **// error**
public void bar(Object e) {...}
public void baz(String s) {...} **// error**
}
公共静态类父类{
公共void foo(集s){…}
公共空白栏{…}
公共void baz(字符串s){…}
}
公共静态类子扩展父{
公共void foo(集合s){…}**//错误**
公共无效条(E){…}**//错误**
//公共空栏(对象e){…}//这是有效的
公共void baz(字符串s){…}
}
公共静态类女儿延伸到父亲{
公共void foo(集合s){…}**//错误**
公共空栏(对象e){…}
公共void baz(字符串s){…}**//错误**
}
正如你所看到的,我犯了几个错误。以下是我的问题:
baz
有效,而foo
无效Son
中的bar
。为什么objecte
工作,而ee
失败?我想E
将被擦除为对象
子
,为什么baz
与子
相比失败了(我知道我不应该使用原始类。但这为什么会导致错误?问题是
Son
扩展了原始父类
因此,Son
类的foo
和bar
不会覆盖
public void foo(Set<String> s) {}
public void bar(S s) {}
并对Son
类中同名的方法进行相同的擦除
将子的声明更改为
public static class Son<E> extends Father<E>
公共静态类子扩展父类
将解决错误
baz
方法没有问题,因为它没有泛型参数,所以子类的baz
覆盖基类的baz
在你的女儿
班上,不清楚T
来自哪里。如果将T
更改为E
,所有错误都会消失
噢,void bar(Object e)
在原始示例中起作用,因为它覆盖了父对象的void bar
(由于子对象扩展了原始父对象)
public class Son<E> extends Father {
使用原始类型也会对继承性产生影响。
从:
原始类型的超类(分别是超接口)是
删除任何
泛型类型的参数化
以及:
类的超类型可以是原始类型。用户的成员访问权限
类被视为正常,并且超类型的成员访问被忽略
作为原始类型处理
因此,<代码>子< /代码>不考虑父类中的泛型。
对于
Son
,此继承方法:
public void foo(Set<String> s) {
}
因此,子方法和父方法具有相同的擦除,但子方法不会重写父方法,因为您使用的类型不完全相同:
public void foo(Set<String> s) {...} **// error**
它将编译
对于带有泛型的bar()
方法,情况完全相同
这:
public void bar(E e)
将约束为:
public void foo(Set s) {
}
public void bar(Object e)
你也会遇到同样的问题
我不会解释所有要点,因为我认为这没有帮助。
你得到的是坏习惯的结果。
士气在于您不必为设计用于泛型的类使用原始类型,因为这可能会对它们的初始意图和类的使用产生严重的副作用。
这个
公共静态类子扩展父类{
应该是:
public static class Son<E> extends Father<E> {
public static class Daughter<E> extends Father<E> {
公共静态类子扩展父类{
这是:
public static class Daughter<E> extends Father<T> {
公共静态类子类扩展父类{
应该是:
public static class Son<E> extends Father<E> {
public static class Daughter<E> extends Father<E> {
公共静态类子类扩展父类{
T.T我知道我不应该使用原始类。但我真的想知道它为什么会导致错误。
public static class Daughter<E> extends Father<T> {
public static class Daughter<E> extends Father<E> {