Java中重载必须在参数类型或参数数量上有所不同,但擦除不能不同,这样的说法正确吗?在重载的情况下不是等价的吗?如果方法的类型或参数数量不同,那么它们的擦除每次也会不同?仅仅因为重载指的是运行时而不是编译时,就说重载必须在擦除上有所不同,这是不正确的吗?
编辑:例如,
foo(List<String>)
和foo(List<Integer>)
具有相同的擦除和不同的参数类型,对吧?但是编译它们会导致错误
java:名称冲突:
和foo(java.util.List<java.lang.Integer>)
具有相同的擦除foo(java.util.List<java.lang.String>)
那么什么更重要呢?擦除还是参数类型?
擦除是在运行时决定的
不,不是。类型的擦除在编译时就已知。您提供的链接实际上是在说“在执行时,类型信息已从对象中删除”。换句话说,如果你只有一个对象的引用,你无法区分
List<String>
和 List<Integer>
之间的区别。
如果一个类的两个方法(无论是在同一个类中声明,还是都由类继承,或者一个声明一个继承)具有相同的名称,但签名不是重写等效的,则该方法名称被称为超载。
这一事实不会造成任何困难,并且其本身也不会导致编译时错误。
如果两个方法或构造函数 M 和 N 具有相同的名称、相同的类型参数(如果有)(第 8.4.4 节),并且在将 N 的形式参数类型调整为类型参数之后,则它们具有相同的签名M,相同的形参类型。
因此,由于方法签名由方法名称和参数列表组成,因此在重载的情况下,重载是具有不同形参类型的同名方法。
根据上述定义,foo(List<String>)
和 foo(List<Integer>)
是 foo
的重载。它无法编译的事实是因为在另一节中指定了规则。
综上所述,定义方法是否重载的不是擦除,而是参数列表。
感谢@Jon Skeet 和@Sweeper 提供宝贵的评论和参考。答案主要是他们的评论和参考文献中的文字的组合