Java 通用示例未编译?

Java 通用示例未编译?,java,generics,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

例如:

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));
  }
}
公共A类{
公众身份证;
}
公共类B扩展了A{
B(){
this.id=“”;
}
}
公共类C扩展到B{
公共财产;
公共静态void main(字符串[]args){
System.out.println(新的C().id.substring(0,1));
}
}
new C().id.substring(0,1)
不会编译,因为id是它所说的对象类型


有什么不对?有没有一种方法可以在不强制转换的情况下执行此操作?

原始类型语言规范的相关部分是:

具体而言:

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

因此,raw
C
的超类是
B
和raw
A
,即使
B
的超类是
A
。(这让我的头有点痛)

下一段说:

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

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

和以往一样,这里的解决办法是

System.out.println(新的C().id.trim());
//^^可以在此处使用任何相关类型,但菱形运算符也适用

同样的代码为我编译,然后将main()方法移动到classA,甚至像预期的那样在索引超出边界的异常情况下运行它。首先,您需要一些代码来重新构造,最好的做法是在公共类中使用main方法,这看起来仍然正确,由于字符串为空,代码使用IndexOutOfBoundException成功编译。@KDM您使用哪个编译器成功编译?eclipse中的JDK1.8.0172。
System.out.println(new C<>().id.trim());
                     // ^^ Can use any relevant type here, but diamond operator works too