【问题标题】:Shouldn't the type T in addToCollection(T[] a, Collection<T> c) be the same?addToCollection(T[] a, Collection<T> c) 中的类型 T 不应该相同吗?
【发布时间】:2016-11-30 23:29:46
【问题描述】:

我不明白为什么下面的代码有效:

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

    public class Main {

        public static void main(String[] args) {
            Integer[] arr=new Integer[]{1,2,3};
            ArrayList<Object> al=new ArrayList<>();
            addToCollection(arr, al);
        }
        static <T> void addToCollection(T[] a, Collection<T> c)
        {
            for(T o:a)
                c.add(o);
        }
    }

不应该是:

...

static <T> void addToCollection(T[] a, Collection<? super T> c)

...?

在调用过程中类型T不应该一样吗?

正如 cmets 中所说,我的问题是“为 T 推断出哪种类型”。由于代码正常工作,我假设推断层次结构中的“更高”类型。

【问题讨论】:

  • 和什么一样?
  • 如果你有一个Bicycle的数组,你不应该把它添加到Vehicle的集合中吗?
  • 他在问为什么允许他通过ArrayList&lt;Object&gt;Integer[]。问题是推断T 是哪种类型,我相信它是Object,但目前没有具体提到JLS。
  • arr 是一个 Object[](因为 Integer[] 是一个 Object[]),而 ArrayList 是一个 Collection,所以可以编译。
  • 请注意,Object[] x = new Integer[10]; 可以编译,但 ArrayList&lt;Object&gt; l = new ArrayList&lt;Integer&gt;(); 不能。

标签: java generics collections


【解决方案1】:

arral 都是 Object 的子类型,所以这就是你得到的。如果您将 addToCollection 函数更改为具有返回类型,则会发生这种情况:

public static class Main {

    public static void main(String[] args) {
        Integer[] arr=new Integer[]{1,2,3};
        ArrayList<Object> al=new ArrayList<>();
        Collection<Object> objects = addToCollection(arr, al);  // Compiles
        Collection<Integer> numbers = addToCollection(arr, al); // Doesn't compile
    }

    static <T> Collection<T> addToCollection(T[] a, Collection<T> c)
    {
        for(T o:a) // Behold the side effect
            c.add(o);

        return c;
    }
}

【讨论】:

  • 那么,第二个 addToCollection(arr, al) 返回一个 Collection&lt;Object&gt; ,对吧?
  • 是的,因为类型不正确,所以无法编译。它只是在那里展示它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-19
  • 1970-01-01
  • 2011-02-03
相关资源
最近更新 更多