添加元素时Java泛型类错误

时间:2014-03-03 23:12:52

标签: 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;
}

}

4 个答案:

答案 0 :(得分:5)

T的输入可以是任何内容。在类中,没有办法知道在列表中放置一个Integer(int自动装箱)是否安全。将T放在List<T>中是唯一安全的。

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

请注意,声明<T extends Integer>不允许您将整数添加到列表中。整数是最终的,但是在一个虚构的Java中,我们可以声明Generator<IntegerSubtype>,它将继续向List<IntegerSubtype>添加一个整数。这可能会导致Integer转换为IntegerSubtype,因此不允许这样做。

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

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

    ListHolder() {
        list.add(new Object());
    }
}

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

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

如果我们为列表提供具体类型,那么从外部看,这样的添加就像这样:

List<String> list = new ArrayList<>();
list.add(new Object()); // Object would be casted to String

对于Integer来说,这是同样的事情,这是不可信的:

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

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

答案 1 :(得分:3)

您正在尝试将一个整数(i) - 特别是for循环的索引 - 转换为ArrayList<T>T列表不是整数列表,因此编译器不允许您这样做。

你需要做这样的事情:

list.add(someTObject);

使整数工作的唯一方法是将T声明为Number:

由于你将Number传递给GenerateList(这是一个函数,实际上应该是小写:generateList),我怀疑你可能希望这个

public class Generator<N extends Number> {

   public ArrayList<N> GenerateList(N n) {    //N, not Number
       ArrayList<N> list = new ArrayList<>();

       for (int i = 0; i < n.intValue(); i++) {  //Must be n.intValue()
           list.add(n);   //THIS WORKS FOR N
       }

       return list;
   }
}

然后在使用类中,将<N>声明为Integer

Generator<Integer> intGen = new Generator<Integer>();
intGen.GenerateList(3);  

我不确定for-terminator现在应该是什么,但我无法想象i < n.intValue()是对的。

答案 2 :(得分:1)

当您尝试使用Generic ArrayList时,它不知道它将存储哪种对象。

我不确定你的意图,但是你应该制作整数类型的ArrayList。 或者,如果您真的希望该方法是通用的,请指定应该允许的超类型。

答案 3 :(得分:0)

名为 list 的ArrayList具有泛型类型 T ,因此您无法向其添加整数项,因为add方法需要类型T或任何扩展它的内容< / p>