我写了下面的代码:
public void test() {
Callable<?> myCall = new Callable() {
@Override
public String call() throws Exception {
return doDomething();
}
};
Callable<?> myCall2 = new Callable() {
@Override
public String call() throws Exception {
return doDomething2();
}
};
ExecutorService executor = Executors.newFixedThreadPool(2);
List<Future<?>> futuresList = executor.invokeAll((Collection<? extends Callable<?>>) getList());
String result1 = futuresList.get(0).get();
String result2 = futuresList.get(0).get();
...
...
}
private List<Callable<?>> getList() {
.. create callables with wildcard and return them
}
我收到以下编译错误:ExecutorService 类型中的方法 invokeAll(Collection>) 不适用于参数 (Collection>)。
编辑 我添加了一个方法 getList 因为我希望它使用泛型而不是 String。 我想了解为什么它不编译。在我的真实程序中,它是一种方法。
最佳答案
您必须了解何时需要泛型中的通配符。在您的示例中,您根本不需要它们。只有当您不知道某个通用对象的类型时才需要它们。在您的示例中,您希望 Callables 返回字符串,因此您应该将其用作泛型类型,如下所示:
public void test() throws InterruptedException, ExecutionException {
Callable<String> myCall = new Callable<String>(){
public String call() throws Exception{
return doDomething();
}
};
Callable<String> myCall2 = new Callable<String>(){
public String call() throws Exception{
return doDomething2();
}
};
ExecutorService executor = Executors.newFixedThreadPool(2);
List<Callable<String>> list = Arrays.asList(myCall, myCall2);
List<Future<String>> futuresList = executor.invokeAll(list);
String result1 = futuresList.get(0).get();
String result2 = futuresList.get(1).get();
executor.shutdown();
}
参见 Sun/Oracle 的 tutorial on generics and wildcards
编辑:
- 将
futuresList.get(0)
更改为futuresList.get(1)
以获得第二个结果 - 添加了
executor.shutdown()
因为人们往往会忘记这一点...
编辑 2:
回应您的评论,这里是另一个例子。这是你可以做这样的事情的一种方式。我想展示如何从调用者一直到 Callables 或更好的 doDomething
方法生成所有涉及的方法。
public void test() throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(2);
List<Callable<String>> list = getList();
List<Future<String>> futuresList = executor.invokeAll(list);
String result1 = futuresList.get(0).get();
String result2 = futuresList.get(1).get();
System.out.println(result1);
System.out.println(result2);
executor.shutdown();
}
private <T> List<Callable<T>> getList() {
Callable<T> myCall = new Callable<T>(){
public T call() throws Exception{
return (T) "a"; //doDomething();
}
};
Callable<T> myCall2 = new Callable<T>(){
public T call() throws Exception{
return (T) "b"; //doDomething2();
}
};
return Arrays.asList(myCall, myCall2);
}
关于java - 使用泛型时出现编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6436807/