泛型错误:不适用于参数

发布于 2024-08-10 20:07:36 字数 1463 浏览 8 评论 0原文

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

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

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

Can someone explain to me why the following code does not work?

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

I'm getting the following error:

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

I've got it to work by altering code as follows:

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

but I want to understand why the original approach did not work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

丿*梦醉红颜 2024-08-17 20:07:36

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

它不会向编译器提供任何信息。 “?”任何类型的意思,所以实际上它太通用了,没有任何意义。

看一下这里: ​​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 通配符的正常误解当你开始使用它们时。这就是有界通配符(例如 )存在的原因,否则通用通配符几乎毫无用处,因为编译器无法对其做出任何假设。

The answer is simple: the unbound wildcard cannot be used. It simply means "uknown object".

It doesn't give anything informative to compiler. "?" means of whatever type, so actually it is too generic to mean anything.

Take a look here: http://java.sun.com/docs/books/tutorial/extra/generics/wildcards.html

As stated:

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

Since we don't know what the element type of c stands for, we cannot add objects to it. The add() method takes arguments of type E, the element type of the collection. When the actual type parameter is ?, it stands for some unknown type. Any parameter we pass to add would have to be a subtype of this unknown type. Since we don't know what type that is, we cannot pass anything in. The sole exception is null, which is a member of every type.

EDIT: don't worry, this is a normal misunderstanding of java wildcard when you start using them. That's why bounded wildcards (eg. <? extends Something>) exist, otherwise generic wildcard would be almost useless since compiler cannot make any assumptions on it.

揽清风入怀 2024-08-17 20:07:36

这不起作用,因为您的类 Client 不是为特定的 Strategy (Strategy) 编写的,而是在 run( ) 方法,您传递一个 String (这仅适用于 Strategy!)。仅当您将 a 的类型和 setStrategy() 的参数更改为 Strategy 类型时,这才有效!

That does not work because your class Client is written for no specific Strategy (Strategy<?>) but in the run() method, you pass a String (which is only correct for Strategy<String>!). That would only work if you'd change a's type and setStrategy()'s parameter to the type Strategy<String>!

于我来说 2024-08-17 20:07:36

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

This is because this is not a type safe operation. "?" is a wildcard that means I do not know the type. It does not mean "any type". read this... http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文