【问题标题】:Java Generics Causing ProblemsJava 泛型导致问题
【发布时间】:2016-08-10 15:18:55
【问题描述】:

我的 IDE 抱怨“NCM_Callable 无法在这一行 this.ph.submitCallable(new NCM_Callable(this, new DeviceGroup(this.deviceGroupNames.get(i)), ph)); In the "fetchDevices()" method 上转换为 Callable<ReturnInterface<? extends Object>>

我只想能够将 Callables 传递给我的 ecs,它返回一个包含任何类型对象的 ReturnInterface。

我怀疑我对 泛型定义的使用有问题,但我似乎无法弄清楚它是什么。任何帮助,将不胜感激。

  @Override
public void fetchDevices() throws Exception {
    System.out.println("[NCM_Fetcher]fetchingDevices()");
    for (int i = 0; i < this.deviceGroupNames.size(); i++) {
        System.out.println("[NCM_Fetcher]fetchingDevices().submitting DeviceGroup Callable " + i+ " of "+this.deviceGroupNames.size());
        this.ph.submitCallable(new NCM_Callable(this, new DeviceGroup(this.deviceGroupNames.get(i)), ph));
    }
    this.ph.execute();//See progressBarhelper below
}

ProgressBarHelper:我在“ecs.submit()”中有一个奇怪的错误。从我读过的内容来看,似乎我可能需要一个辅助方法?我该如何解决?

public class ProgressBarHelper extends SwingWorker<Void, ReturnInterface> implements ActionListener {
ExecutorService pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

protected CompletionService<ReturnInterface<?>> ecs;

public final void submitCallable(Callable<? extends ReturnInterface<?>> c) {
    //create a map for this future
    ecs.submit(c);
    this.callables.add(c);//Error here is Callable<CAP#1 cannot be converted to Callable<ReturnInterface<?>>
    System.out.println("[ProgressBarHelper]submitted");

}
}

最后是 NCM_Callable 类及其泛型。

public class NCM_Callable implements Callable<ReturnInterface<ResultSet>>, ReturnInterface<ResultSet> {

【问题讨论】:

  • 首先创建一个minimal reproducible example。您可能会在此过程中解决您的问题。
  • 不是重复的。
  • 它解决了你的问题吗?查看第二个答案,您必须将方法签名更改为使用Callable&lt;? extends ReturnInterface&lt;? extends Object&gt;&gt; c
  • 顺便说一句,&lt;? extends Object&gt; 和刚才的&lt;?&gt; 是一样的

标签: java generics


【解决方案1】:

据我所知,有问题的行是ecs.submit

public final void submitCallable(Callable<? extends ReturnInterface<?>> c) {
    // create a map for this future
    ecs.submit(c); // Error here is Callable<CAP#1 cannot be converted to Callable<ReturnInterface<?>>
   this.callables.add(c); // this is fine on my machine
}

问题是java泛型是invariant。有一个解决方法:您可以将通配符替换为命名的绑定类型

public final <T extends ReturnInterface<?>> void // this is how you name and bind the type
   submitCallable(Callable<T> c) { // here you are referring to it
    // create a map for this future
    ecs.submit((Callable<ReturnInterface<?>>) c); // here you need to cast. 
    ...
}

由于type erasure,在运行时可以进行转换。但是在处理这些Callables 时要非常小心。

最后,你可以这样调用这个函数:

private static class ReturnInterfaceImpl implements ReturnInterface<String>  {

};

public void foo() {
    Callable<ReturnInterfaceImpl> c = new Callable<ReturnInterfaceImpl>() {
        @Override
        public ReturnInterfaceImpl call() throws Exception {
            return null;
        }
    };
    submitCallable(c);
}

【讨论】:

  • 我很沮丧,最终接受了一个可调用的。有人可以解释为什么我的代码不起作用,这很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-04
  • 1970-01-01
相关资源
最近更新 更多