generics错误:不适用于参数

有人可以向我解释为什么以下代码不起作用?

public class Test { interface Strategy { void execute(T t); } public static class DefaultStrategy implements Strategy { @Override public void execute(T t) {} } public static class Client { private Strategy a; public void setStrategy(Strategy a) { this.a = a; } private void run() { a.execute("hello world"); } } public static void main(String[] args) { Client client = new Client(); client.setStrategy(new DefaultStrategy()); client.run(); } } 

我收到以下错误:

 The method execute(capture#3-of ?) in the type Test.Strategy is not applicable for the arguments (String) 

我通过改变代码来实现它,如下所示:

 public class Test { interface Strategy { void execute(T t); } public static class DefaultStrategy implements Strategy { @Override public void execute(T t) {} } public static class Client { private Strategy a; public void setStrategy(Strategy a) { this.a = a; } private void run(T t) { a.execute(t); } } public static void main(String[] args) { Client client = new Client(); client.setStrategy(new DefaultStrategy()); client.run("hello world"); } } 

但我想理解为什么原始方法不起作用。

答案很简单:无法使用未绑定的通配符。 它只是意味着“未知对象”。

它没有给编译器提供任何信息。 “?” 无论什么类型的手段,所以实际上它太过于通用而不是任何意义。

看看这里: http : //java.sun.com/docs/books/tutorial/extra/generics/wildcards.html

就像声明的那样:

 Collection c = new ArrayList(); c.add(new Object()); // Compile time error 

由于我们不知道c的元素类型代表什么,我们无法向其添加对象。 add()方法接受类型为E的参数,即集合的元素类型。 当实际类型参数是?时,它代表某种未知类型。 我们传递给add的任何参数都必须是这种未知类型的子类型。 因为我们不知道它是什么类型,所以我们无法传递任何内容。唯一的例外是null,它是每种类型的成员。

编辑:不用担心,这是开始使用它时对java通配符的正常误解。 这就是存在有界通配符(例如 )的原因,否则通用通配符将几乎无用,因为编译器无法对其做出任何假设。

这不起作用,因为您的类Client不是针对特定StrategyStrategy )编写的,但是在run()方法中,您传递一个String (仅对Strategy !)。 只有当你将类型和setStrategy()的参数更改为Strategy类型时, setStrategy()

这是因为这不是类型安全的操作。 “?” 是一个通配符,这意味着我不知道这种类型。 它并不意味着“任何类型”。 阅读本文… http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf