Java中重载必须参数类型或参数个数不同,但擦除不能不同吗?

问题描述 投票:0回答:1

擦除在运行时决定并且要调用的重载方法在编译时解决

Java中重载必须在参数类型或参数数量上有所不同,但擦除不能不同,这样的说法正确吗?在重载的情况下不是等价的吗?如果方法的类型或参数数量不同,那么它们的擦除每次也会不同?仅仅因为重载指的是运行时而不是编译时,就说重载必须在擦除上有所不同,这是不正确的吗?

编辑:例如,

foo(List<String>)
foo(List<Integer>)
具有相同的擦除和不同的参数类型,对吧?但是编译它们会导致错误

java:名称冲突:

foo(java.util.List<java.lang.Integer>)
foo(java.util.List<java.lang.String>)
具有相同的擦除

那么什么更重要呢?擦除还是参数类型?

java overloading type-erasure
1个回答
0
投票

擦除是在运行时决定的

不,不是。类型的擦除在编译时就已知。您提供的链接实际上是在说“在执行时,类型信息已从对象中删除”。换句话说,如果你只有一个对象的引用,你无法区分

List<String>
List<Integer>
之间的区别。

JLS重载路段

如果一个类的两个方法(无论是在同一个类中声明,还是都由类继承,或者一个声明一个继承)具有相同的名称,但签名不是重写等效的,则该方法名称被称为超载。

这一事实不会造成任何困难,并且其本身也不会导致编译时错误。

签名在JLS的另一节中定义

如果两个方法或构造函数 M 和 N 具有相同的名称、相同的类型参数(如果有)(第 8.4.4 节),并且在将 N 的形式参数类型调整为类型参数之后,则它们具有相同的签名M,相同的形参类型。

因此,由于方法签名由方法名称和参数列表组成,因此在重载的情况下,重载是具有不同形参类型的同名方法。

根据上述定义,

foo(List<String>)
foo(List<Integer>)
foo
的重载。它无法编译的事实是因为在另一节中指定了规则。

综上所述,定义方法是否重载的不是擦除,而是参数列表。


感谢@Jon Skeet 和@Sweeper 提供宝贵的评论和参考。答案主要是他们的评论和参考文献中的文字的组合

© www.soinside.com 2019 - 2024. All rights reserved.