1

给定这个简单的类:

    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<T>,错误就会消失,但这不是我想要的。copy() 方法对任何类型的 GenericTest 都有效,而不仅仅是 GenericTest<T>。

4

3 回答 3

2

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

public Collection getKeys() {
    return null;
}

所以,如果你迭代原始类型的方法,你会得到getKeys(),而不是,我不明白你为什么期望。GenericTestObjectString

来自JLS 第 4.8 节 - 原始类型

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


你真的应该GenericTest<T>在你的方法中使用作为参数类型,而不是原始类型。并将返回类型更改getKeysCollection<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, 在您的课程中。


参考:

于 2013-08-16T15:47:52.613 回答
1

你可能想写

public void copy(GenericTest<String> a_from) {

或者

public void copy(GenericTest<T> a_from) {

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

于 2013-08-16T15:48:46.630 回答
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);
    }
}
于 2013-08-16T15:49:29.713 回答