我在一个班级中有以下方法:
void delete(ClassA a) {
//....
}
void delete(ClassB b) {
//...
}
void delete(List<ClassA> list) {
for (ClassA a: list) {
delete(a);
}
}
void delete(List<ClassB> list) {
for (ClassB b: list){
delete(b);
}
}
前两种方法的重载工作正常。但是第三种和第四种方法之间存在冲突。
是否可以用一种方法替换它们?我尝试了以下方法,这是不正确的:
void delete(List<? extends Object> list){
for (Object o: list){
delete((o.getClass())o);
}
}
如何在运行时检测列表中实例的类类型并调用适当的方法?
答案 0 :(得分:3)
重载在编译时解决,因此您不能依赖运行时类型。
您可以做的是使用instanceof
检查运行时类型并明确地转换为相关类型:
void delete(List<? extends Object> list){
for (Object o: list) {
if (o instanceof ClassA) {
delete((ClassA) o);
} else if (o instanceof ClassB) {
delete((ClassB) o);
}
}
}
答案 1 :(得分:1)
您尝试删除List<ClassA>
与List<ClassB>
的不同实现。您可以在Java中执行此操作,但不能使用相同的方法名称。
因此,您可以拥有一个deleteAList(List<ClassA> aList)
和一个deleteBList(List<ClassB> bList)
。
从技术上讲,重载意味着不同的方法共享相同的基本名称,但具有不同的参数类型,因此编译器知道要调用的方法。
或者换句话说,有效的方法名称由您创建的名称和参数类型组成。并且在引入泛型之前定义了该概念,因此它只看到delete(List list)
,忽略了您添加到List
的泛型类型参数。所以你有两个相同的有效方法名称的方法,这就是编译器所抱怨的。
因此,通过使方法基本名称不同来帮助编译器,一切正常。