Java 泛型错误:不适用于参数

Java 泛型错误:不适用于参数,java,generics,bounded-wildcard,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 Cli

有人能给我解释一下为什么下面的代码不起作用吗

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();
 }
}
公共类测试{
接口策略{
无效执行(T);
}
公共静态类DefaultStrategy实现了该策略{
@凌驾
公共无效执行(T){}
}
公共静态类客户端{
私人战略a;
公共政策(策略a){
这个a=a;
}
私家车{
a、 执行(“你好世界”);
}
}
公共静态void main(字符串[]args){
客户端=新客户端();
client.setStrategy(新的DefaultStrategy());
client.run();
}
}
我得到以下错误:

The method execute(capture#3-of ?) in the type Test.Strategy<capture#3-of ?> 
is not applicable for the arguments (String)
方法在类型测试中执行(捕获#3-of?)。策略
不适用于参数(字符串)
我通过如下更改代码使其工作:

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");
 }
}
公共类测试{
接口策略{
无效执行(T);
}
公共静态类DefaultStrategy实现了该策略{
@凌驾
公共无效执行(T){}
}
公共静态类客户端{
私人战略a;
公共政策(策略a){
这个a=a;
}
私人空位运行(T){
a、 执行(t);
}
}
公共静态void main(字符串[]args){
客户端=新客户端();
client.setStrategy(新的DefaultStrategy());
client.run(“hello world”);
}
}

但是我想理解为什么最初的方法不起作用。

这不起作用,因为您的类
客户机
不是为特定的
策略
策略
)编写的,但是在
run()
方法中,您传递了一个
字符串
(这只适用于
策略
!)。只有将
a
的类型和
setStrategy()
的参数更改为类型
策略
,这才有效

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

它没有给编译器提供任何信息。“?”表示任何类型,所以实际上它太泛化了,没有任何意义

请看这里:

如上所述:

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Compile time error
Collection c=newarraylist();
c、 添加(新对象());//编译时错误
因为我们不知道c的元素类型代表什么,所以我们不能向它添加对象。add()方法接受类型为E的参数,即集合的元素类型。当实际类型参数为?时,它表示某个未知类型。我们传递要添加的任何参数都必须是此未知类型的子类型。因为我们不知道那是什么类型,所以我们不能传递任何信息。唯一的异常是null,它是每种类型的成员


编辑:别担心,当您开始使用java通配符时,这是对java通配符的正常误解。这就是为什么有界通配符(例如,
这是因为这不是一个类型安全的操作。“?”是一个通配符,表示我不知道类型。它不表示“任何类型”。请阅读此