首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >泛型上界外卡给出编译错误

泛型上界外卡给出编译错误
EN

Stack Overflow用户
提问于 2016-11-20 11:41:43
回答 3查看 169关注 0票数 0

我在试一些关于泛型上/下界的示例程序。泛型上界给编译error...But下界很好。我只是想把T类型的列表放到一个集合中,同时尝试上下界场景。

请帮助识别testUpperBound( it )方法的问题,以及为什么testLowerBound(It)方法编译和testUpperBound(It)方法没有编译,我检查了其他类似的threads..But,但我还没有弄清楚。

如果需要更多细节,请告诉我。

代码语言:javascript
运行
复制
 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);
        }

    }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-11-20 12:14:13

在这里你有你的答案:

Explanation of the get-put principle

这是java规则,仅此而已。我可以用您的代码举例说明,如果编译通过了,为什么会不安全:

代码语言:javascript
运行
复制
public void extendsExample(){
  Set<? extends List<? extends String>> setOfList = new HashSet<>();
  Set<ArrayList<String>> setOfArrayList = new HashSet<>();

  // now setOfList var refers to a set 
  // which contains a arraylist of String
  setOfList = setOfArrayList;

  // compilation fails
  setOfList.add(new LinkedList<String>());
 }

假设编译没有失败。

它意味着setOfArrayList实例,它是一个应该包含ArrayList实例的集合,现在包含一个LinkedList元素的列表。

如果您在setOfArrayList上迭代,您将不会像预期的那样拥有独占的ArrayList<String>元素。这是不安全的,这也是编译失败的原因。

下面是使用<? super的示例:

代码语言:javascript
运行
复制
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);
}
票数 0
EN

Stack Overflow用户

发布于 2016-11-20 11:48:20

不能修改用<? extends SomeType>参数化的集合。Java只是不允许这样做,因为它不是安全的操作。add()修改集合,因此不能这样做。<? super SomeType>没有这样的限制。

票数 0
EN

Stack Overflow用户

发布于 2016-11-20 12:34:37

简单地说,我们在编译时不知道upperBoundSet中包含了什么类型的列表。它可以是Set<ArrayList<T>>,也可以是Set<LinkedList<T>>,也可以是其他许多替代方案之一。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40703609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档