鉴于这个简单的课程:
import java.util.Collection;
public class GenericTest<T> {
public Collection<String> getKeys() {
return null;
}
public void copy(GenericTest a_from) {
for (String x : a_from.getKeys()) {
}
}
}
我收到以下编译错误,但不明白为什么。
error: incompatible types
for (String x : a_from.getKeys()) {
required: String
found: Object
如果我将参数更改为copy()方法为GenericTest&lt; T&gt;,则错误消失,但这不是我想要的。 copy()方法对任何类型的GenericTest都有效,而不仅仅是GenericTest&lt; T&gt;。
答案 0 :(得分:2)
这不是您创建泛型类的方式。如果使用泛型类的原始类型,则在类中使用的所有参数化类型都会丢失其类型信息。因此,对于GenericTest
原始类型,getKeys()
方法签名更改为:
public Collection getKeys() {
return null;
}
因此,如果您对getKeys()
原始类型的GenericTest
方法进行迭代,则会得到Object
,而不是String
,我不明白为什么您期望
来自JLS Section 4.8 - Raw Types:
未从其超类或超接口继承的原始类型C的构造函数(第8.8节),实例方法(第8.4节,第9.4节)或非静态字段(第8.3节)M的类型是原始的在与C对应的泛型声明中对应于其类型擦除的类型。
您应该在方法中使用GenericTest<T>
作为参数类型,而不是原始类型。并将getKeys
的返回类型更改为Collection<T>
。
将您的课程更改为:
public class GenericTest<T> {
public Collection<T> getKeys() {
return null;
}
public void copy(GenericTest<T> a_from) {
for (T x : a_from.getKeys()) {
}
}
}
类型T
来自您为此泛型类创建的参数化类型。对于GenericTest<String>
,T
将在您的班级中被视为String
。
<强>参考:强>
答案 1 :(得分:1)
public void copy(GenericTest<String> a_from) {
或
public void copy(GenericTest<T> a_from) {
这对我来说也很奇怪,
这里的解释(这是重复的):
Why won't this generic java code compile?
答案 2 :(得分:1)
也许你想要:
public void copy(GenericTest<?> a_from) {
for (String x : a_from.getKeys()) {
}
}
根据您的要求,这将接受任何通用类型。
我修改了你的类,只是因为它不会返回null
集合,并且我使for
循环打印出读取的字符串。
这是结果,编译(并运行)就好了。
import java.util.Collection;
import java.util.ArrayList;
public class GenericTest<T> {
public Collection<String> getKeys() {
ArrayList<String> a = new ArrayList<String>();
a.add("1");
a.add("2");
a.add("3");
return a;
}
public void copy(GenericTest<?> a_from) {
for (String x : a_from.getKeys()) {
System.out.println(x);
}
}
public static void testIt() {
GenericTest<Integer> gti = new GenericTest<Integer>();
GenericTest<String> gts = new GenericTest<String>();
gts.copy(gti);
}
}