为什么类型化的 List<> 的元素在子类中使用时被强制转换为 Object



谁能解释为什么类型化List<>的元素在子类中使用时被强制转换为Object
仅当父类使用泛型时,才会发生这种情况。

在某些类type如何干扰实例字段的type

public abstract class Parent<T> {
protected List<String> myList = Arrays.asList("Hello", "World");
void method1(){
myList.get(0).substring(0, 1); //ok
}
}

public class Child<T> extends Parent {
void method2(){
myList.get(0).substring(0, 1); //compilation error. myList.get(0) is of type Object and not of type String
((String) myList.get(0)).substring(0, 1); // works good, but why we need to cast 
}
}

更新
正如公认的答案所表明的那样,扩展通用Parent<>而不是Parent,将解决问题。
使用泛型和扩展行类型的完整示例:

public abstract class Parent<T extends MyObject> {
}
public class Child<T extends MyObject> extends Parent<T> {
}

这是问题所在:

public class Child extends Parent

因为您使用了原始类型Parent,所以Parent定义中的所有泛型都会丢失,实际上。从JLS的第4.8节:

原始类型的超类(

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

"擦除"部分是"你丢失所有泛型"的行话。

Child中引用类型参数时,需要指定类型参数。例如,您可以保留一个非泛型子类:

public class Child extends Parent<UUID>

或者也使子类泛型:

public class Child<T> extends Parent<T>

最新更新