在这种情况下,为什么编译器不能限制返回类型

Twi*_*ght 1 java

我有以下课程:

Class Container<E extends Supertype>{
    ...
    public ArrayList<E> getList(){...}
    ...
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试这样做时:

public void someFunction(Container x){
    ....
    for(Supertype s : x.getList()){
        ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

它给出了一个编译错误,说明的元素x.getList()Object.但是,由于元素必须是E必须是子类的类型Supertype,为什么编译器不能"解决这个问题"?

我的第一个想法是由于原始类型的问题,但不仅仅是编译器不确定某些东西在运行时是否合法?


是的,我能做到

public void someFunction(Container<?> x)
Run Code Online (Sandbox Code Playgroud)

当我通过原始时,它甚至不会给出一个未经检查的警告Container.只是尝试在这里学习Java的怪癖.

Sot*_*lis 5

是的,这是原始类型的问题.使用某些原始类型的值时,将删除所涉及的任何泛型.

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

其参数具有(或没有)边界的泛型类型的擦除是类型本身.

参数化类型(第4.5节)的擦除G<T1,...,Tn>|G|.

下列

public ArrayList<E> getList() {...}
Run Code Online (Sandbox Code Playgroud)

public ArrayList getList() {...}
Run Code Online (Sandbox Code Playgroud)

这使得 ArrayList#iterator()

public Iterator<E> iterator() {...}
Run Code Online (Sandbox Code Playgroud)

成为

public Iterator iterator() {...}
Run Code Online (Sandbox Code Playgroud)

制造 Iterator#next()

public E next();
Run Code Online (Sandbox Code Playgroud)

成为

public Object next();
Run Code Online (Sandbox Code Playgroud)