繁体   English   中英

类型擦除和覆盖通用方法

[英]Type erasure and overriding generic method

我对泛型的理解是,如果我有public void saveAll(Collection<? extends Object> stuff) {则compile会将输入参数的“最常见类型”确定为Collection<Object> 现在,我用下面的代码重写了通用方法,但是在重写方法中出现了以下错误消息- Name clash: The method saveAll(Collection<? extends Object>) of type ChildWithGenericMethod has the same erasure as saveAll(Collection<Object>) of type ParentWithGenericMethod<T> but does not override it

public class ParentWithGenericMethod {
    public void saveAll(Collection<Object> stuff) {

    }
}

public class ChildWithGenericMethod extends ParentWithGenericMethod{
    public void saveAll(Collection<? extends Object> stuff) {

    }
}

我想知道的是,在类型擦除之后,这些方法的外观如何,我认为它们看起来像是public void saveAll(Collection stuff) {因此,我应该能够重写,因为如果我不使用泛型,那我可以像这样覆盖

请注意,我知道在使用“ javap”编译后可以看到字节码,但是它没有告诉我在“类型擦除”之后这些方法的外观。


更新:
这个问题没有回答我的问题,如果在类型擦除之后两个方法都变为public void saveAll(Collection stuff) {那么子类为什么会覆盖错误,因为使用public void saveAll(Collection<Object> stuff) {它会通过覆盖规则。

值得记住运行时与编译时分派。

一秒钟拿走仿制药。

public class Parent {
  public void saveAll(Object x) {
  }
}

public class Child extends Parent {
   public void saveAll(String x) {
  }
}

public String x = "hello";
public Object y = new Integer(334);
public Object z = "goodbye";

public Child c1 = new Child();

c1.saveAll(x); // invokes Child.saveAll
c1.saveAll(y); // invokes Parent.saveAll
c1.saveAll(z); // invokes Parent.saveAll even though z contains a String

现在将泛型重新纳入故事。

 public class Child<T extends Object> extends Parent {
   public void saveAll(T x) {
  }
}

在这里,saveAll重载而不是覆盖父级的saveAll。

用异物代替T吗? 并没有真正改变这一点-编译器正在尝试创建一个重载父方法的方法,但随后意识到它不能分派编译时类型。

[编辑,请参阅Lew Block对原始内容的评论:编译器需要类型擦除之前确定子方法是重写还是重载父方法]

如果在类型擦除之后,这两个方法都变为public void saveAll(Collection stuff){那么子类为什么会覆盖错误,因为使用public void saveAll(Collection stuff){它会通过覆盖规则。

问题(再次参见Lew Bloch的评论)是重写是类型擦除之前确定的。 在类型擦除之前,父方法和子方法具有不同的签名,因此编译器将它们创建为重载方法,而不是覆盖方法。 在类型擦除之后,编译器意识到它处于绑定中,因为它现在具有两个具有相同签名的方法,并且不知道如何分派。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM