通用示例无法编译?

时间:2018-09-12 06:09:30

标签: java generics

具有以下示例:

public class A<S> {
  public S id;
}

public class B extends A<String> {
  B(){
    this.id = "";
  }
}

public class C<K> extends B {
  public K property;

  public static void main(String[] args) {
    System.out.println(new C().id.substring(0,1));
  }
}

new C().id.substring(0,1)无法编译,因为id表示它是Object类型。

出什么问题了,有没有办法做到这一点而无需强制转换?

1 个答案:

答案 0 :(得分:3)

原始类型的语言规范的相关部分为JLS Sec 4.8为:

特别是:

  

原始类型的超类(分别是超接口)是对泛型类型的任何参数化的超类(超接口)的擦除。

因此,即使C的超类是B,原始A的超类是B和原始A<String>。 (这使我的头部有些受伤)。

下一段说:

  

未从其超类或超接口继承的原始类型C的构造函数(§8.8),实例方法(§8.4,§9.4)或非静态字段(§8.3)的类型为原始类型对应于对应于C的通用声明中其类型的擦除。

因此,id字段的类型是对S的擦除,即Object

和以往一样,这里的解决方法是don't use raw types

System.out.println(new C<>().id.trim());
                     // ^^ Can use any relevant type here, but diamond operator works too