generics编译问题:不兼容的类型

鉴于这个简单的类:

import java.util.Collection; public class GenericTest { public Collection 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 ,则错误消失,但这不是我想要的。 copy()方法对任何类型的GenericTest都有效,而不仅仅是GenericTest 。

这不是您创建generics类的方式。 如果使用generics类的原始类型,则在类中使用的所有参数化类型都会丢失其类型信息。 因此,对于GenericTest原始类型, getKeys()方法签名更改为:

 public Collection getKeys() { return null; } 

所以,如果你遍历GenericTest原始类型的getKeys()方法,你将得到Object ,而不是String ,我不明白为什么你期望。

来自JLS第4.8节 – 原始类型 :

未从其超类或超接口inheritance的原始类型C的构造函数(第8.8节),实例方法(第8.4节,第9.4节)或非静态字段(第8.3节)M的类型是对应的原始类型在对应于C的通用声明中擦除其类型


您应该在方法中使用GenericTest作为参数类型,而不是原始类型。 并将getKeys的返回类型更改为Collection

将您的class级更改为:

 public class GenericTest { public Collection getKeys() { return null; } public void copy(GenericTest a_from) { for (T x : a_from.getKeys()) { } } } 

类型T来自您为此generics类创建的参数化类型。 对于GenericTestT将在您的类中被称为String


参考:

  • Angelika Langer – Java Generics FAQ
    • 如何定义generics类型

你可能想写

 public void copy(GenericTest a_from) { 

要么

 public void copy(GenericTest a_from) { 

这对我来说也很奇怪,这里的解释(这是重复的): 为什么这个通用的java代码不会编译?

也许你想要:

 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 { public Collection getKeys() { ArrayList a = new ArrayList(); 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 gti = new GenericTest(); GenericTest gts = new GenericTest(); gts.copy(gti); } }