泛型上限通配符会出现编译错误

时间:2016-11-20 11:41:44

标签: java generics

我正在尝试一些关于泛型上/下界的示例程序。泛型上界正在给出编译错误......但下限很好。 我只是试图将类型T的List放入一个集合中并尝试上限和下限场景..

请帮助确定testUpperBound(T t)方法的问题,以及为什么testLowerBound(T t)方法正好编译而testUpperBound(T t)方法没有。我检查了其他类似的线程..但我仍然没有说清楚。

如果需要更多详细信息,请告诉我。

 public class TestGenerics<T> 
    {

        public static void main(String...args)
        {
           List<String> list = new ArrayList<>();
           list.add("New ArrayList");
           new TestGenerics<List<String>>().testUpperBound(list);
           new TestGenerics<List<String>>().testLowerBound(list);

        }

       public  void testLowerBound(T t)
       {
            Set<? super ArrayList<T>> lowerBoundSet = new HashSet<>();
            lowerBoundSet = new HashSet<List<T>>();
            ArrayList<T> list = new ArrayList<>();
            list.add(t);
            lowerBoundSet.add(list);  // compiles..

            out.println(lowerBoundSet);
        }

        public  void testUpperBound(T t)
        {
            Set<? extends List<T>> upperBoundSet = new HashSet<>();
            upperBoundSet = new HashSet<List<T>>();
            ArrayList<T> list = new ArrayList<>();
            list.add(t);
            upperBoundSet.add(list);  // Doesn't compile..

            out.println(upperBoundSet);
        }

    }

3 个答案:

答案 0 :(得分:0)

您无法修改使用<? extends SomeType>参数化的集合。 Java只是不允许这样做,因为它不是安全的行动。 add()修改集合,因此您无法执行此操作。 <? super SomeType>

没有此类限制

答案 1 :(得分:0)

这里有答案:

Explanation of the get-put principle

这是java规则,就是这样。 我可能会给你一个代码示例,为什么在编译通过时它会不安全:

setOfArrayList

想象一下编译不会失败。
这意味着ArrayList实例是一个应包含LinkedList个实例的集合,现在包含setOfArrayList元素的列表。

如果您对ArrayList<String>进行迭代,则不会按预期排除<? super个元素。这不安全,这就是编译失败的原因。

这里的示例包含public void superExample(){ Set<? super ArrayList<String>> setOfArrayList = new HashSet<>(); // compilation ok setOfArrayList.add(new ArrayList<String>()); // new anonymous type derivating from ArrayList ArrayList<String> derivedArrayList = new ArrayList<String>(){ }; // compilation ok setOfArrayList.add(derivedArrayList); }

algoliasearch.angular.js

答案 2 :(得分:0)

简单地说,我们在编译时不知道upperBoundSet中包含哪种类型的列表。它可以是Set<ArrayList<T>>,也可以是Set<LinkedList<T>>,也可以是许多其他选择之一。

如果结果是Set<LinkedList<T>>,那么添加ArrayList显然是一个坏主意。但是因为我们不知道该集合的内容是什么类型,所以它需要更安全的选项并阻止它。