2016-12-01 4 views
3

를 사용하여 올바른 문을 얻고 나는 Callables 다른 반환 형식이 invokeAll을어떻게 내가 ExecutorService를 사용하고 제네릭

를 사용하여 실행할 수 있도록 Callables을 생성하고 싶어합니다. 어느 날 나는이 나에게 컴파일러 오류 내가 해결하는 방법을 받고 있지 않다 The method invokeAll(Collection<? extends Callable<T>>) in the type ExecutorService is not applicable for the arguments (Set<Callable<?>>)을 제공 invokeAll을

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

광고에 대한 문을 추가 유사한 방식으로 와일드 카드

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

를 사용하여 끝낼 수 있다고 생각했다.

누군가가 사용상의 오류와 올바른 사용법을 지적 할 수 있습니까? 컴파일러 오류가 JDK 6에서 내가 생각하지 않습니다까지

그냥 머리가 더 높은 버전에서 다른 될 것입니다 JDK

PS : - 유사한 StackOverflow의 스레드가이 Collection of Callable and Generics

에뿐만 아니라있다

답변

2

문제는 invokeAll의 서명이 너무 제한적이라는 것입니다. T는 여기서 제작자이기 때문에 Collection<? extends Callable<? extends T>>이어야합니다 (Effective Java : PECS - Producer Extend Consumer Super를 기억하십시오). 그러나 여기서는 JDK 메서드를 변경할 수 없으므로 함께 살 필요가 있습니다.

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

마지막 문 : 해결 방법은 Set<Callable<Object> 전달>와 중 안전하지 않은 캐스트를 사용 (안전 인 경우에만 호출 가능에서 타입 T의 값을 추출하기 때문에) 또는 메소드 참조를 사용하는 것입니다 아래처럼 보일 것입니다

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

응답 주셔서 감사합니다. 위의 구문은 괜찮습니다. 저는 여전히 마지막 문장을 수정하는 방법을 얻지 못합니다 List > futures = executorService.invokeAll (executedCallables); – Acewin

+1

당신은'List >를 확장하면 List >을 얻을 수 있습니다. 'T'를 와일드 카드로 만들 수있는 방법이 없습니다. – diesieben07

+0

감사합니다.이 점을 솔루션에 추가하는 것이 좋습니다 – Acewin

관련 문제