java - 使用泛型时出现编译错误

标签 java generics

我写了下面的代码:

 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/

相关文章:

java - 如何将 Object 类型转换为 List<Object> 类型?

Java RMI : Determining Caller process from Callee

generics - Ada 含糊不清的表达与 Get

c# - 为什么我们*应该*使用 EventHandler

java - Java 中对封闭类的隐式引用

java - 创建用于管理和解析命令参数的参数处理程序

c# - 具有未指定类型的泛型类的数组

java - java中删除标点符号

java - 上传图像时输入未存储在数据库中

java - map 内 map 迭代