java泛型超级关键字 [英] java generics super keyword

查看:115
本文介绍了java泛型超级关键字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经历了这些主题



然而,我似乎仍然因 super 关键字而丢失:


  1. 当我们声明如下集合时:

     列表< ;?超级号码> list = null; 
    list.add(new Integer(0)); //编译
    list.add(new Object()); //这不会编译

    不应该是相反的 - 我们有一个包含一些对象(未知类型)的列表,它们是编号。因此 Object 应该适合(因为它是 Number 的父项),并且 Integer 不应该。由于某些原因,情况正好相反。


  2.   static void test(List< ;? super Number> param){
    param.add(new Integer(2));
    }
    public static void main(String [] args){
    ArrayList< String> sList = new ArrayList< String>();
    test(sList); //不会编译,但是...
    }

    不可能编译上面的代码(我的理智认为这是正确的行为),但基本逻辑可能证明是相反的:

    String是Object,Object是Number的超类。因此,字符串应该工作。



    我知道这很疯狂,但这不是他们不允许< S super T> 结构?如果是,那么为什么<?是否允许超级T>


    这个逻辑链?

    解决方案 中 List中的有界通配符<? super Number> 可以捕获 Number 及其任何超类型。由于 Number扩展Object实现了Serializable ,这意味着目前只能被 List <?>捕获转换的类型。超级数字> 为:




    • List< Number>

    • List< Object>



    请注意,您可以 add(Integer.valueOf(0))到任何上述类型。但是,您不能 将(新对象())添加到 List< Number>

    因此它是或a List< Serializable> em> 真可以添加任何超类型的数字名单< ;?超级号码> ;这根本不是多么有界的通配符和捕获转换工作。您不要声明列表< ;? super number> ,因为你可能想添加一个 Object 给它(你不能!);你这样做是因为你想为它添加 Number 对象(即它是 Number 的消费者),并且只是

    参考



    List< Number> 限制太多。

    另见




    • Effective Java第2版,第28项:使用有界通配符来增加API灵活性


      • 生产者 - 扩展,消费者 - 超级




    • 相关的问题




      • 太多列表,PECS, 新的整数(0) vs valueOf


      I went through these topics

      However, I still seem to be kind of lost with super keyword:

      1. When we declare a collection like that:

        List<? super Number> list = null;
        list.add(new Integer(0));//this compiles
        list.add(new Object());//this doesn't compile
        

        shouldn't it be the opposite - we have a list that contains some objects (of unknown type) which are parents of Number. So Object should fit (since it is the parent of Number), and Integer shouldn't. The opposite is the case for some reason.

      2. Provided we have the following code

        static void test(List<? super Number> param) {
            param.add(new Integer(2));
        }
        public static void main(String[] args) {
            ArrayList<String> sList = new ArrayList<String>();
            test(sList);            //will never compile, however...
        }
        

        It is impossible to compile the above code (and my sanity suggests that this is the right behaviour), but the basic logic could prove the opposite:

        String is Object, Object is superclass of Number. So String should work.

        I know this is crazy but isn't this the reason why they didn't allow <S super T> constructs? If yes, then why <? super T> is allowed?

      Could someone help me to restore the missing part of this logic chain?

      解决方案

      The bounded wildcard in List<? super Number> can capture Number and any of its supertypes. Since Number extends Object implements Serializable, this means that the only types that are currently capture-convertible by List<? super Number> are:

      • List<Number>
      • List<Object>
      • List<Serializable>

      Note that you can add(Integer.valueOf(0)) to any of the above types. however, you CAN'T add(new Object()) to a List<Number> or a List<Serializable>, since that violates the generic type safety rule.

      Hence it is NOT true that you can add any supertype of Number to a List<? super Number>; that's simply not how bounded wildcard and capture conversion work. You don't declare a List<? super Number> because you may want to add an Object to it (you can't!); you do because you want to add Number objects to it (i.e. it's a "consumer" of Number), and simply a List<Number> is too restrictive.

      References

      See also

      • Effective Java 2nd Edition, Item 28: Use bounded wildcards to increase API flexibility
        • "PECS stands for producer-extends, consumer-super

      Related questions

      • Too many to list, PECS, new Integer(0) vs valueOf, etc

      这篇关于java泛型超级关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆