2016-12-01 61 views
3

所以我用的ExecutorService,想要產生可調用,這樣我可以使用的invokeAll如何得到正確的語句中使用泛型

的可調用對象有不同的返回類型執行。這讓我覺得我可以以類似的方式,使用通配符

Set<Callable<?>> executedCallables = new HashSet<Callable<?>>(); 
executedCallables.add(serviceHelper.getOwnerDetails()); --> returns Callable<OwnerDetails> 
executedCallables.add(iqmServiceHelper.getUserDetails()); --> returns Callable<UserDetails> 

我添加語句的invokeAll

List<Future<? extends Object>> futures = executorService.invokeAll(executedCallables); 

廣告這給了我編譯器錯誤The method invokeAll(Collection<? extends Callable<T>>) in the type ExecutorService is not applicable for the arguments (Set<Callable<?>>)這我沒有得到如何解決得到完成。

有人可以指出使用中的錯誤和正確的用法。

剛擡起頭編譯器錯誤是JDK 6,我不認爲將是更高的版本不同的JDK

PS: - 有一個類似的StackOverflow線程以及這個Collection of Callable and Generics

回答

2

問題是invokeAll的簽名有點過於嚴格。它應該是Collection<? extends Callable<? extends T>>,因爲T在這裏是一個生產者(記得從Effective Java:PECS - Producer Extends Consumer Super)。 但是,我們當然不能在這裏更改JDK方法,所以我們必須忍受它。溶液處於Set<Callable<Object>傳遞>和或者使用一個不安全的鑄造(其是安全的,因爲你只提取類型T的值出來的可贖回的)或使用方法參考:

Set<Callable<Object>> callables = new HashSet<>(); 
callables.add((Callable) serviceHelper.getOwnerDetails()); // method one 
callables.add(iqmServiceHelper.getUserDetails()::call); // method two 

最終聲明看起來像下面

try { 
    List<Future<Object>> futures = executorService.invokeAll(executedCallables); 
} catch (InterruptedException e) { 
    e.printStackTrace(); 
} 
+0

感謝您的答覆。上述聲明構造良好我還沒有得到如何糾正最終陳述列表<未來<? extends Object >> futures = executorService.invokeAll(executedCallables); – Acewin

+1

你不會拿出一個'List >',你會得到'List >'。 這裏沒有辦法使'T'成爲通配符。 – diesieben07

+0

謝謝,我會建議你把這點加到你的解決方案中 – Acewin