添加元素时Java泛型类错误

Gre*_*989 -1 java oop generics

这是一个Generator类,它应该填充元素的ArrayList.

当我调用list.add(i)时,我不明白为什么会收到错误消息;

我也尝试将int解析为<T>并调用list.add((T)i),但这也不起作用.

public class Generator<T> {

public ArrayList<T> GenerateList(Number n) {
    ArrayList<T> list = new ArrayList<>();

    for (int i = 0; i < (int) n; i++) {
        list.add(i); //Error on this line (No suitable method found for add(int))
    }

    return list;
}
Run Code Online (Sandbox Code Playgroud)

}

Rad*_*def 5

打字T可以是任何东西.在类中,没有办法知道在列表中放置一个Integer(int自动装箱)是否安全.放入一个T是安全的List<T>.

没有办法将具体对象添加到通用列表中.列表必须具有明确接受Integer的具体类型List<Object>,List<Number>或者List<Integer>.

请注意,声明这<T extends Integer>不会让您将Integer添加到列表中.整数是最终的,但是在一个假想的组合Java中,它不是,我们可以声明一个Generator<IntegerSubtype>将继续添加一个Integer到一个List<IntegerSubtype>.这可能会在以后导致Integer获取,IntegerSubtype因此不允许这样做.

最后一点的简化示例如下:

class ListHolder<T extends Object> {
    List<T> list = new ArrayList<>();

    ListHolder() {
        list.add(new Object());
    }
}
Run Code Online (Sandbox Code Playgroud)

(这也用于说明其余部分,因为无界类型参数通常会将Object作为上限.)

T是有限的,但更明显的是,列表可能无法容纳对象.实际上因为Object没有超类,所以除了a之外,不能放入任何对象List<Object>.通过在列表中放置一个Object,我们可能(并且可能是)稍后会错误地将其向下转换为子类型.

如果我们为列表提供具体类型,那么从外部看,这个添加只是如下所示:

List<String> list = new ArrayList<>();
list.add(new Object()); // Object would be casted to String
Run Code Online (Sandbox Code Playgroud)

这对Integer来说是一回事,这简直难以置信:

List<IntegerSubtype> list = new ArrayList<>();
list.add(new Integer(3)); // Integer would be casted to IntegerSubtype
Run Code Online (Sandbox Code Playgroud)

(我说只是'难以置信',因为我认为sun.misc.Unsafe在正常的Java中使用......不可能欺骗最终类的子类型.)