【问题标题】:Generic type lost for member of raw type原始类型成员的通用类型丢失
【发布时间】:2013-10-08 13:10:19
【问题描述】:

我在使用泛型时发现了一个奇怪的行为。

在 Foo<T> 这个类中,strings 成员与 T 没有任何关系:

package test;
import java.util.ArrayList;

public class Foo<T> {
    ArrayList<String> strings;

    T getSome() {
        return null;
    }
}

该类用于main:

package test;

public class Main {

    public static void main() {
        Foo<Integer> intFoo = new Foo<>();
        Integer i = intFoo.getSome();
        String s1 = intFoo.strings.get(0);

        Foo rawFoo = new Foo();
        Object o = rawFoo.getSome();
        String s2 = rawFoo.strings.get(0); // Compilation error on this line
    }
}

编译错误是“不兼容的类型。必需:找到的字符串:对象”。

当使用 Foo 的原始类型时,Java 似乎忘记了 ArrayList 的 String 类型参数。

我的java版本是1.7.0_21

【问题讨论】:

  • 这是完全正常的。原始类型是完全原始的(所有成员)。请搜索类似问题。
  • 原始类型是为了向后兼容。来自java tutorial on raw types:“使用原始类型时,您基本上会获得预泛型行为”。如果 Foo 具有泛型成员(即使它不依赖于 T),则 Foo 的原始类型将不会向后兼容

标签: java generics


【解决方案1】:

简单地说,因为rawFoo是原始的,它的非静态成员也变成了原始的。

这在JLS §4.8中有所概述:

更准确地说,原始类型被定义为以下之一:

  • 通过采用没有伴随类型参数列表的泛型类型声明的名称形成的引用类型。

  • 元素类型为原始类型的数组类型。

  • 不是从 R 的超类或超接口继承的原始类型 R 的非静态成员类型。

注意最后一个项目符号。

【讨论】:

  • 最后一个项目符号实际上是指内部类(非静态成员 type),而不是字段。
猜你喜欢
  • 2020-03-05
  • 2011-02-13
  • 2021-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-04
  • 1970-01-01
相关资源
最近更新 更多