Java 泛型错误:不适用于参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1684121/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
generics error: not applicable for the arguments
提问by
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.
但我想了解为什么原来的方法不起作用。
回答by Johannes Weiss
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>
!
这是行不通的,因为您的类Client
不是为特定的Strategy
( Strategy<?>
) 而编写的,但是在run()
方法中,您传递了 a String
(仅适用于Strategy<String>
!)。这只有在您将a
的类型和setStrategy()
参数更改为类型时才有效Strategy<String>
!
回答by Hyman
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
看看这里: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.
因为我们不知道 c 的元素类型代表什么,所以我们不能向它添加对象。add() 方法接受类型为 E 的参数,即集合的元素类型。当实际类型参数为 ? 时,它代表某种未知类型。我们传递给 add 的任何参数都必须是这种未知类型的子类型。因为我们不知道那是什么类型,所以我们不能传入任何东西。唯一的例外是 null,它是所有类型的成员。
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.
编辑:别担心,这是当您开始使用它们时对 java 通配符的正常误解。这就是有界通配符(例如<? extends Something>
)存在的原因,否则通用通配符几乎没有用,因为编译器无法对其进行任何假设。
回答by Matthew Sowders
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
这是因为这不是类型安全的操作。“?” 是通配符,表示我不知道类型。它并不意味着“任何类型”。读这个... http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf