使用泛型类型参数进行Java重载

时间:2017-08-17 07:33:34

标签: java generics overloading

我在一个班级中有以下方法:

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);
  }
}

如何在运行时检测列表中实例的类类型并调用适当的方法?

2 个答案:

答案 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的泛型类型参数。所以你有两个相同的有效方法名称的方法,这就是编译器所抱怨的。

因此,通过使方法基本名称不同来帮助编译器,一切正常。