Oracle的Collection <object>教程令人困惑

时间:2018-06-13 15:53:35

标签: java object generics collections

我正在学习Java泛型并通过Generic Methods阅读。

此页面以

开头
  

考虑编写一个方法,该方法接受一组对象和一个集合,并将数组中的所有对象放入集合中

然后说明

  

到目前为止,您将学会避免初学者错误地尝试使用Collection<Object>作为集合参数的类型。

该页面推断使用Collection<Object>将无效。

为什么会出错?为什么这是初学者的错误?

Collection<Object>因为参数对我来说很好。我是如此初学者,我以某种方式使代码有效,但错过了练习的重点?

import java.util.ArrayList;
import java.util.Collection;

public class test {

    static void fromArrayToCol(Object a[],Collection<Object> c)
    {
     for (Object x:a){c.add(x);}
     System.out.println(c);
    }

    public static void main(String[] args) {
        test r=new test();
        Object[] oa=new Object[]{"hello",678};
        Collection<Object> c=new ArrayList<>();

        test.fromArrayToCol(oa,c);
    }
}

在我看来,Oracle的教程在其断言中是错误的。但我是初学者,所以很可能我没有抓住它试图告诉我的内容。

5 个答案:

答案 0 :(得分:2)

如果您阅读Wildcards部分,可以找到答案。

  

问题是这个新版本比旧版本更有用。虽然可以使用任何类型的集合作为参数调用旧代码,但新代码仅使用Collection,正如我们刚刚演示的那样,它是所有类型集合的超类型! / p>

此处,旧版本引用参数Collection,而新代码引用Collection<Object>

当您拥有Collection<Object>类型的参数时,您可以传递Collection(原始类型)或Collection<Object>。您无法传递任何其他代码,例如Collection<String>Collection<SomeClass>

因此,该教程的目标是将包含任何类型的数组元素复制到相同类型的新集合中。 示例: Integer[]Collection<Integer>

我想说出上述含义并不恰当。

答案 1 :(得分:0)

这通常是一个错误,不是因为它是编译器错误,而是因为拥有Collection<Object>很少有用。这样的集合可以容纳任何东西。您多久需要一个可以容纳任何东西的集合? 很少。几乎总会有一个更具体的类型参数可用于您的收藏。

经常使用Collection<Object>会使程序员的生活变得更加艰难。为了得到任何东西,我们需要检查它的类型(例如使用instanceof)并投射它。

通过使用最合适的类型参数,您可以自己编译时保证集合只包含您希望它将的对象类型,结果代码更简洁,更易读

答案 2 :(得分:0)

澄清。如果在编译时不知道集合的类型,则无法在其中放入元素。

在您当前的示例中,您确实知道要放入集合的对象类型(在您的情况下,它是一个对象)。您喜欢的网站上显示的示例是

static void fromArrayToCollection(Object[] a, Collection<?> c) {
    for (Object o : a) { 
        c.add(o); // compile-time error
    }
}

请注意,?而不是Object。因此,您会收到编译时错误。

在您在问题中显示的使用Object的示例中,它会编译;但是,有更好的方法来解决这个问题。

最大的问题是它只适用于扩展具有泛型类型Object的集合的类型。这使得它非常有限。该页面告诉您,只要它们具有相同的类型,就有一种方法适用于任何集合和数组。

答案 3 :(得分:0)

the beginner's mistake他们指的是当您打算接受任意时尝试使用Collection<Object>作为参数 收集的东西

因为Object是所有java类的超类,所以可以认为Collection<Object>是&#34;超级集合&#34;所有收藏品。这一点在Wildcard部分中进行了演示:

  

问题是这个新版本比旧版本更有用。虽然可以使用任何类型的集合作为参数调用旧代码,但新代码仅使用Collection,正如我们刚刚演示的那样,它不是所有类型集合的超类型!

而不是Collection<Object>您必须使用Collection<T>来表示您的方法接受任何内容集合

答案 4 :(得分:0)

我认为这也是一个选择:

private <T> void arrayToCollection(T[] objArray, Collection<T> collection) {

    for (T obj : objArray) {
        collection.add(obj);
    }
}