2017-08-17 135 views
3

超载我在一个类中的以下方法:与Java泛型类型参数

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

使用'instanceof'来检查对象 – soorapadman

回答

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

难道不可能只是说“将o强制转换为任何它是实例的类”吗?没有明确地将其转换为该类? –

+1

@ArianHosseinzadeh不,编译器必须知道传递给'delete'参数的编译时间类型,以确定应该调用哪个重载方法。 – Eran

1

你想有不同的实现了List<ClassA>List<ClassB>删除。你可以用Java做到这一点,但不能用相同的方法名称。

所以,你可以有一个deleteAList(List<ClassA> aList)和一个deleteBList(List<ClassB> bList)

从技术上讲,重载意味着不同的方法共享相同的基本名称,但具有不同的参数类型,因此编译器知道要调用哪个方法。

或者换句话说,有效的方法名是由您创建的名称和参数类型组成的。而且这个概念是在引入泛型之前定义的,所以它只是看到delete(List list),忽略了添加到List的泛型类型参数。所以你有两个相同的有效方法名的方法,这就是编译器所抱怨的。

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