`
lg_asus
  • 浏览: 184622 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

java 协变 逆变 不可变

阅读更多
参考:http://blog.csdn.net/zero__007/article/details/52245475

文章没转过来,下面是个人结论:
协变:子类的方法返回值可以是父类的子类型。但是方法形参不能是父类方法形参的子类型。
逆变:协变的反类型。
协变的应用是多态和里氏替换原则。

List<Number>并不是List<Integer>的父类型,两者没有任何关系。

List<Number> d = new ArrayList<Number>();//可以添加Number及Number的任何子类元素

List<? extends Number> d2 = new ArrayList<Integer>();//? extends规定了上限。不能添加除了null之外的任何元素。因为d2具体应用的list对象可以是Integer也可以是Float、Double等,所以不能添加确定的Number元素。

List<? super Number> d3 = new ArrayList<Number或者Object>();//? super规定了下限,可以添加Number的任何子类,但是不能添加Number的父类。

所以d2和d3中能不能添加元素、添加什么类型的元素关键看和后面具体的集合对象有没有可能存在冲突,如果存在冲突那肯定就不能添加元素了。

什么时候用? extends,什么时候用? super,有个PECS法则,即producer extends, consumer super。在一个集合是数据提供方就用? extends,是数据消费方就用? super。如代码:
public static <T> void copy(List<? super T> dest, List<? extends T> src) {  
    int srcSize = src.size();  
    if (srcSize > dest.size())  
        throw new IndexOutOfBoundsException("Source does not fit in dest");  
  
    if (srcSize < COPY_THRESHOLD ||  
        (src instanceof RandomAccess && dest instanceof RandomAccess)) {  
        for (int i=0; i<srcSize; i++)  
            dest.set(i, src.get(i));  
    } else {  
        ListIterator<? super T> di=dest.listIterator();  
        ListIterator<? extends T> si=src.listIterator();  
        for (int i=0; i<srcSize; i++) {  
            di.next();  
            di.set(si.next());  
        }  
    }  
}  

这也就告诉我们,在自定义带list泛型方法的时候,如果这个方法是要消费形参传入进来的数据,这时形参是数据提供方,要定义成list<? extends T> src,如果方法是要产生数据并传给形参,这时形参是数据消费方,要定义成list<? super T> dst。
分享到:
评论

相关推荐

    C#协变逆变

    协变逆变代码示例 -只是简单的讲解协变和逆变以及自定义协变逆变 -讲解地址https://blog.csdn.net/qq_29756987/article/details/94626915

    理解C#中的协变和逆变

    一个可以让你轻松理解协变和逆变的小程序,你的进步是我最大的快乐

    详解c# 协变和逆变

    协变和逆变在泛型参数中的表现方式,out关键字表示协变,in关键字表示逆变。二者只能在泛型接口或者委托中使用。 理解协变和逆变 看完上面的定义是不是一脸懵逼~~~。看不懂就对了,且定义语句的歧义性很大。让我们...

    31-协变-逆变-双向协变(赋值操作).ts

    31-协变-逆变-双向协变(赋值操作)

    协变和逆变 京华志

    协变和逆变 京华志 京华志出品 必数精华

    C#中的协变与逆变深入讲解

    泛型类型参数支持协变和逆变,可在分配和使用泛型类型方面提供更大的灵活性。 一开始我总是分不清协变和逆变,因为MSDN的解释实在是严谨有余而易读不足。 其实从中文的字面上来理解这两个概念就挺容易的了: “协...

    Kotlin中协变、逆变和不变示例详解

    super T&gt; 通配符型变约束,而是采用类似 C# 的 in,out 用于支持协变和逆变,这同时避免了处理子类型化,父类化的问题(即Java泛型中典型的List&lt;T&gt; 不是 List&lt;Object&gt;的子类型的问题); 基本的泛型语法可以...

    C#逆变与协变详解

    在Java中同样存在逆变与协变,后续我还会写一篇Java逆变协变的文章,有兴趣的朋友可以关注一下。 逆变与协变,听起来很抽象、高深,其实很简单。看下面的代码: class Person { } class Student : Person { } ...

    基于.Net中的协变与逆变的深入分析

    本篇文章是对.Net中的协变与逆变进行了详细的分析介绍,需要的朋友参考下

    c#协变和逆变实例分析

    主要介绍了c#协变和逆变,以实例形式详细讲述了协变和逆变的原理与具体用法,具有一定的学习借鉴价值,需要的朋友可以参考下

    你了解C#的协变和逆变吗,看完这篇就懂了

    主要介绍了你了解C#的协变和逆变吗,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    C#4.0新特性之协变与逆变实例分析

    本文实例讲述了C#4.0新特性的协变与逆变,有助于大家进一步掌握C#4.0程序设计。具体分析如下: 一、C#3.0以前的协变与逆变 如果你是第一次听说这个两个词,别担心,他们其实很常见。C#4.0中的协变与逆变(Covariance...

    Java语言 泛型讲解案例代码 (泛型类、泛型接口、泛型方法、无界及上下限通配符、泛型对协变和逆变的支持、类型擦除 ...)

    本代码资源是一个关于Java语言中泛型的讲解案例代码。通过使用实际的示例代码,详细讲解了泛型的定义、用法和优势。 适用人群: 有一定Java编程基础的开发者;对泛型概念感兴趣或希望加深理解的学习者。 使用场景...

    整流逆变整流逆变整流逆变

    整流逆变整流逆变整流逆变整流逆变整流逆变整流逆变整流逆变整流逆变

    逆变电源逆变电源逆变电源

    关于逆变电源的资料关于逆变电源的资料关于逆变电源的资料关于逆变电源的资料关于逆变电源的资料关于逆变电源的资料 关于逆变电源的资料关于逆变电源的资料关于逆变电源的资料关于逆变电源的资料关于逆变电源的资料...

    一篇文章看懂C#中的协变、逆变

    官方:协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型。[MSDN] 公式:  协变:IFoo&lt;父类&gt; ...

    单极性正弦脉宽调变逆变器实验报告.docx

    自动化专业,电气工程及其自动化专业可用

Global site tag (gtag.js) - Google Analytics