具有以下示例:
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类型。
出什么问题了,有没有办法做到这一点而无需强制转换?
答案 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