java泛型 - 参数不能应用于方法

时间:2011-10-03 14:42:54

标签: java generics


我似乎无法弄清楚为什么我试图制作的方法调用不起作用。
在问这个问题之前我已经看了很多,虽然有很多关于类似问题的线索,但我找不到一个非常适合我的问题。
我有以下代码:

(在文件Processor.java中:)

public interface Processor
{
    Runner<? extends Processor> getRunner();
}

(在文件Runner.java中:)

public interface Runner<P extends Processor>
{
    int runProcessors(Collection<P> processors);
}

(在某些其他文件中,在某些方法中:)

Collection<? extends Processor> processorsCollection = ...;
Runner<? extends Processor> runner = ...;
runner.runProcessors(processorsCollection);


IntelliJ将最后一行标记为错误:
Runner中的“RunProcessors(java.util.Collection&gt;)”无法应用于(java.util.Collection&gt;)“。
我无法弄清楚我做了什么错了,特别是因为错误信息不太清楚。

有什么建议?

感谢。

2 个答案:

答案 0 :(得分:8)

您的收藏和跑步者都可以使用扩展处理器的任何内容。但是,你无法保证它们是一样的。

收藏可能是Collection<Processor1>,而收件人可能是Runner<Processor2>

无论你需要输入哪种方法(我忘记确切的语法,但我相信你能找到它!)

void <T extends Processor<T>> foo() {
    Collection<T> procColl = ...
    Runner<T> runner = ...
    runner.runProc(procColl);
}

编辑:

@newAcct提出了一个很好的观点:你需要对你的处理器进行泛化(这是一个字吗?)。我已更新上面的代码段,以反映这一重要更改。

public interface Processor<P extends Processor>
{
    Runner<P> getRunner();
}

public interface Runner<P extends Processor<P>>
{
    int runProcessors(Collection<P> processors);
}

答案 1 :(得分:0)

你没有明确你的情况,你没有向我们展示方法的任何代码或你如何获得对象,所以我们真的不知道你想要做什么。

您的代码不是类型安全的。正如@glowcoder所提到的,无法知道Collection的参数与Runner的参数相同。如果您认为它们确实相同,那么这是基于您没有向我们展示的代码(即“...”中会发生什么?)

您编写了Processor的{​​{1}}方法,其返回类型具有通配符参数。这说明在运行时它将返回一个getRunner(),其中包含一个它确定但我们不知道的神秘参数。这没有多大意义,可能不是你想要的。

同样取决于你在做什么,Runner方法可能会采取不太严格的约束。例如,如果您不需要修改集合,可能是runProcessors甚至<? extends P>