【问题标题】:why this is not overloading? [duplicate]为什么这不超载? [复制]
【发布时间】:2023-03-14 13:06:02
【问题描述】:
我有以下两种方法
public void add(List<String> strs) {...}
public void add(List<Integer> ints) {...}
我得到编译错误,所以我的问题是为什么它没有重载,那么使用泛型有什么好处?
这是我得到的错误:
Method add(List<Integer>) has the same erasure add(List<E>) as another method in type Child
【问题讨论】:
标签:
java
generics
overloading
【解决方案1】:
Java 泛型是仅编译时的语言特性;泛型类型(例如这里的String 和Integer)在编译过程中被擦除,而字节码只包含原始类型,如下所示:
public void add(List strs) {...}
因此,您不能拥有多个签名仅在泛型类型中不同的方法。有几种方法可以解决这个问题,包括可变参数和使您的方法本身具有通用性,最佳方法取决于具体任务。
泛型的优势在于,在采用List<String> 的方法中,您可以在List 中添加或删除元素,并将它们视为String 对象,而无需在任何地方添加显式转换。
【解决方案2】:
泛型类型在运行时被擦除。所以你的 public void add(List<String> strs) 和 public void add(List<Integer> ints){...........} 是相同的类型,编译器只是对你可以用它们做什么设置编译时限制。
【解决方案3】:
当您针对泛型类型或方法编译一些代码时,编译器会计算出您真正的意思(即 T 的类型参数是什么)并在编译时验证您正在做正确的事情,但发出的代码再次只是根据 java.lang.Object 进行讨论 - 编译器会在必要时生成额外的强制转换。在执行时,一个List<Integer> 和一个List<String> 完全相同;额外的类型信息已被编译器删除。
因此你得到编译错误。
【解决方案4】:
在Java 中,您可以执行以下操作(重载),参数列表包含List。
public void add(List strs){
}
如果您使用不同类型的List 具有相同的方法名称,它将被视为相同的方法。
【解决方案5】:
请记住,JVM 不会决定在运行时调用哪个方法。与虚拟方法相反,重载方法的方法覆盖解析是在编译时完成的。 method overloading 上的 Java 教程甚至指出“应谨慎使用重载方法……”。