泛型错误:不适用于参数

7 java generics bounded-wildcard

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

public class Test {

 interface Strategy<T> {
   void execute(T t);
 }

 public static class DefaultStrategy<T> implements Strategy<T> {
   @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<String>());
   client.run();
 }
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

The method execute(capture#3-of ?) in the type Test.Strategy<capture#3-of ?> 
is not applicable for the arguments (String)
Run Code Online (Sandbox Code Playgroud)

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

public class Test {

 interface Strategy<T> {
  void execute(T t);
 }

 public static class DefaultStrategy<T> implements Strategy<T> {
   @Override
   public void execute(T t) {}

 }

 public static class Client<T> {
   private Strategy<T> a;

   public void setStrategy(Strategy<T> a) {
     this.a = a;
   }

   private void run(T t) {
     a.execute(t);
   }
 }

 public static void main(String[] args) {
   Client<String> client = new Client<String>();
   client.setStrategy(new DefaultStrategy<String>());
   client.run("hello world");
 }
}
Run Code Online (Sandbox Code Playgroud)

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

Jac*_*ack 12

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

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

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

就像声明的那样:

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Compile time error
Run Code Online (Sandbox Code Playgroud)

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

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


Joh*_*iss 0

这是行不通的,因为你的类Client是为没有特定的Strategy( Strategy<?>) 编写的,但在run()方法中,你传递了 a String(这仅适用于Strategy<String>!)。a仅当您将's type 和setStrategy()'s 参数更改为 type时,这才有效Strategy<String>