7

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

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();
 }
}

我收到以下错误:

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

我通过如下更改代码使其工作:

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");
 }
}

但我想了解为什么原来的方法不起作用。

4

3 回答 3

12

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

它没有为编译器提供任何信息。“?” 意味着任何类型,所以实际上它太笼统而无法表示任何东西。

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

就像声明的那样:

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Compile time error

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

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

于 2009-11-05T22:42:27.147 回答
0

这不起作用,因为您的类Client是为没有特定的Strategy( Strategy<?>) 而编写的,但是在run()方法中,您传递了 a String(仅对Strategy<String>! 是正确的)。仅当您将a' 类型 和setStrategy()' 参数更改为type 时,这才有效Strategy<String>

于 2009-11-05T22:40:52.050 回答
0

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

于 2009-11-05T22:54:35.443 回答