Generic error: not applicable to arguments

Can someone explain to me why the following code is not working?

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 get 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 need this to work by changing the 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.

+6
java generics bounded-wildcard
source share
3 answers

The answer is simple: an unrelated template cannot be used. It just means "baptized object."

This does not give anything informative to the compiler. "?" means of any type, so this is actually too general to mean anything.

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

As noted:

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

Since we do not know what the type of element c means, we cannot add objects to it. The add () method accepts arguments of type E, the type of the item in the collection. When is the actual type parameter ?, it means some unknown type. Any parameter that we pass to add must be a subtype of this unknown type. Since we do not know what it is, we cannot convey anything. The one exception is null, which is a member of each type.

EDIT: don't worry, this is a normal misunderstanding of the java template when you start using them. Therefore, there are limited wildcards (for example, <? extends Something> ), otherwise the general template will be almost useless, since the compiler cannot make any assumptions.

+11
source share

This does not work because your Client class is written without special Strategy ( Strategy<?> ), But in the run() method you pass String (which is true only for Strategy<String> !). This will only work if you change type a and setStrategy() to type Strategy<String> !

0
source share

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

0
source share

All Articles