2017-08-17 170 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的泛型類型參數。所以你有兩個相同的有效方法名的方法,這就是編譯器所抱怨的。

因此,通過使方法基名不同,幫助編譯器,並且一切正常。