1. 基础泛型//定义泛型类,接口的定义和类一样class A {

T t;

P p;// extends 限定泛型上界

public  M doSomething(M params) {}

}

关于泛型的使用基本如此,开发者可以在实际使用时灵活地指定泛型所对应的实际类型,从而达到不同的效果

2. 协变与逆变与不变协变

在Java中的数组是协变的,简单来说即有:A extends B  ==>  A[] extends B[]

B[] bs = new A[2]; //合法逆变

与协变相对,逆转了类型关系不变Java 语言中的泛型基本上完全在编译器中实现,由编译器执行类型检查和类型推断,然后生成普通的非泛型的字节码。这种实现技术称为擦除(erasure)(编译器使用泛型类型信息保证类型安全,在生成字节码之前将其清除,替换为非泛型上界)

由于泛型擦除的原因,Java中的泛型是不变的,因此在使用泛型的地方(比如集合)中List bls = new ArrayList();//不合法

编译器检查不通过,我们假设B可以有其它的子类比如C,由于bls的引用指定的类型是B,所以C extends B

bls.add(new C())

显然应该是合法的,但事实上bls指向的实例指定的类型是A,而A与C并没有直接继承关系,这就导致类型异常的问题。但是显然问题不能就这样结束,因此为了解决泛型的不变,就需要用到通配符?与extends、super。

3. 通配符? 与 extends 与 super

先以泛型集合List为例来说明以上三个关键字的特性

(1)通配符?在单独使用时可以看作是? extends ObjectList> l0= new ArrayList();

(2)? extends xxx使得泛型具有协变的特性,extends限定了泛型的上界//extends包含指向类及其子类List extends Number> l1= new ArrayList();List extends Number> l2= new ArrayList();l1.add(new Integer(1));//无法编译Number n = l1.get(0);//可以获取到

当向l1中add一个元素,不管是任何类型的元素,都是不合法的,因为泛型下界无法确定,比如Integer和Double同是Number的子类,但是一个指向List的实例add一个Double类型的元素显然是不合法的;当从l1中get一个元素,泛型上界确定是Number

(3)? super xxx使得泛型具有逆变的特性,super限定了泛型的下界//super包含指向类及其父类List super Integer> l3 = new ArrayList();List super Integer> l4 = new ArrayList();l3.add(new Integer(1));//可以编译Object o = l3.get(0);//可以获取到

想要向l3中add一个元素,泛型下界确认为Integer,那么这个元素必须是Integer及其子类的类型;当从l3中get一个元素时,由于JAVA中所有类型总是Object的子类,所以泛型上界可以确定是Object

总结一点就是:写入需要有类型下界,而读出需要有类型上界

在Android中,一个典型的例子就是RxJava的map操作public final  Observable map(Function super T, ? extends R> mapper) {

ObjectHelper.requireNonNull(mapper, "mapper is null");    return RxJavaPlugins.onAssembly(new ObservableMap(this, mapper));

}public interface Function {    /**

* Apply some calculation to the input value and return some other value.

* @param t the input value

* @return the output value

* @throws Exception on error

*/

R apply(@NonNull T t) throws Exception;

}

作者:白与兰与白兰地

链接:https://www.jianshu.com/p/43beda48c665

bls java_JAVA泛型与类型安全相关推荐

  1. 泛型类java_Java泛型 - 通用类( Generic Classes)

    Java泛型 - 通用类( Generic Classes) 泛型类声明看起来像非泛型类声明,除了类名后跟一个类型参数部分. 泛型类的类型参数部分可以有一个或多个用逗号分隔的类型参数. 这些类称为参数 ...

  2. bls java_Java PairingFactory.getPairing方法代碼示例

    本文整理匯總了Java中it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory.getPairing方法的典型用法代碼示例.如果您正苦於以下問題:Java ...

  3. new泛型 java_Java泛型

    一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: 1 public class GenericTest { 2 3 public static void main(Stri ...

  4. Java笔记(三)内部类,容器,泛型和类型安全的容器,迭代器

    继续内部类 package java_learn;class call1 implements incrementable{private int i;@Overridepublic void inc ...

  5. 简化java_Java泛型太复杂了?如何简化?

    最初我在codereview上发布了这个问题,但这可能更适合stackoverflow. 我用Java 6编码一个多步骤的过程.假设有3个步骤. 每个都接受相同类型的输入. 我们开始吧. 这是作为输入 ...

  6. 深入Java泛型(一):作用与定义

    一.泛型的基本概念 泛型的定义: 泛型是JDK 1.5的一项新特性,它的本质是参数化类型(Parameterized Type)的应用,也就是说所操作的数据类型被指定为一个参数,在用到的时候在指定具体 ...

  7. .NET泛型解析(上)

    [1]:泛型介绍 泛型是C#2.0中一个重要的新特性,泛型是CLR和编程语言提供的一种特殊机制,它支持另一种形式的代码重用.泛型通常用与集合以及作用于集合的方法一起使用,当然也可以单独使用. C#是一 ...

  8. Java程序员从笨鸟到菜鸟之(十)枚举,泛型详解

    一:首先从枚举开始说起 枚举类型是JDK5.0的新特征.Sun引进了一个全新的关键字enum来定义一个枚举类.下面就是一个典型枚举类型的定义: public enum Color{ RED,BLUE, ...

  9. java 泛型集合应用_Java泛型集合的应用和方法

    展开全部 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以62616964757a686964616fe78988e69d8331333 ...

最新文章

  1. 第十二届河南省ACM大学生程序设计竞赛赛后总结
  2. IdentityHash as hashMap
  3. 标题:浅析图卷积神经网络
  4. ObjecT4:On-line multiple instance learning (MIL)学习
  5. [转]史上最全的后端技术大全,你都了解哪些技术呢?
  6. HH SaaS电商系统的商品物流模板的功能设计
  7. wifi定位算法android,WIFI定位算法
  8. .Net Core 1.1打包发布到Linux
  9. 系统权限控制设计001---RBAC用户角色权限设计方案
  10. java集成微信扫码登录
  11. OpenDDS环境搭建-Windows 10
  12. java中IOException是什么异常
  13. 微信转发指定的图文消息到朋友圈(JAVA版)
  14. attention方式的算法
  15. 【阿里巴巴】学习Java在面试过程中跳槽成功的心得总结
  16. 前端不让浏览器自动填充账号密码
  17. 磁盘阵列(RAID)级别的简单介绍
  18. el-select如何选择整个对象item
  19. mysql month函数值类型_MySQL常用函数(分类别整理)
  20. 2011 模拟 c语言 本科(含答案)(第二届“国信蓝点杯”全国软件专业人才设计与开发大赛)...

热门文章

  1. layer.prompt添加多个输入框
  2. 为什么Java中只有值传递
  3. 一台服务器多个tomcat运行
  4. SVN使用教程总结[转]
  5. android之Handler Runnable实现倒计时
  6. 用FPGA实现视频中物体边缘二值化
  7. WPF and Silverlight 学习笔记(十九):WPF更换主题
  8. windows--bat--%0无限执行当前bat脚本
  9. Linux下Ubuntu关闭触摸板(TinkPad)
  10. AndroidStudio安卓原生开发_activity之间复杂对象类型的数据传递---Android原生开发工作笔记92