概述
  1. 泛型就是参数化类型,一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参,其实你回味一下这里。形参参数化的是变量的值,而如果你想参数化变量的类型,那就用到泛型了。同样的, 定义的时候叫类型形参,使用时传入类型实参
    1. 所以很多时候你会遇到,定义一个方法的时候,形参的类型和值都是用变量表示的,比如:<T> T[] toArray(T[] a);
  2. 所以 , 泛型就是把类中或者方法中某些数据的类型也作为参数来传递,使得代码更加灵活
  3. 对比:
    1. 我把以前的做:参数化变量、变量形参、变量实参
    2. 现在的叫做:参数化类型、类型形参、类型实参
  4. 其实两个还有很大区别的:
    1. 参数化变量只在定义方法的时候会使用,对类没有参数化变量一说,实例化类传递的参数实际上只是构造方法的参数
    2. 而参数化类型不仅在定义方法的时候使用,还在定义类的时候会使用到,这点上它会带来很大的不同
      1. 参数化类型能通过形式参数限定实际参数范围。类比参数化变量,是这样的样子:比如变量类型是Int,你要求int的范围是0到100,于是有 int<100> a;
      2. 本来类之间的相对关系只有一个维度(虽然类似是一个树图),两个类之间有明确的上下关系或者是没有关系(即使算上多重继承),但如果一个类又有了参数化类型的尾巴的话,那类之间的关系又有了一个新的维度,造成的结果可能是这个维度上,A在上B在下,而在另一个维度,B在上A在下,不过目前JAVA就规定尾巴的维度不使用
        1. 这里可能对于尾巴这个维度有一点异议,因为它比较复杂
          1. 在定的时候,一般如果是<T>,那这个维度可以说没有,但如果对这个T有extends的话,那确实会有一个范围,会有一个上下关系
          2. 在使用的,这种上下关系就很明显了,T本身的取值就是类型,它的上下关系会造成外面 Class<T>的上下关系吗
      3. 对类的使用场景有:定义类的时候,实例化类的时候,声明对象类型的时候(多态)
        1. 前两种情况比较简单,但是第三种情况就需要实际面临上面提到的问题【在使用的,这种上下关系就很明显了,T本身的取值就是类型,它的上下关系会造成外面 Class<T>的上下关系吗 】,你需要找到一个基类
 
泛型分 泛型类/接口 和 泛型方法
  1. 实例化泛型类的时候需要显式传递泛型参数,使用泛型方法则一般通过参数传递
 
而应用情景又分为:
  1. 定义泛型时(定义泛型时只能发生在 类/接口的定义 和方法的定义时)
    1. 定义泛型--类/接口,就是在定义类的时候指定某个类型为参数。形式是这样,<>写在定义的类的名称的后边: class Box<T> { .......}
    2. 定义泛型--方法,就是在定义方法的时候指定某个类型为参数。形式是这样,<>写在方法的public 后 void前:public  <T> T[] toArray(T[] a);
  2. 使用泛型时
    1. 使用泛型可以发生在 任何时候,包括 类/接口的定义 和方法的定义时
    2. 使用方法就是把本来应该写类型名称的位置改成你定义的泛型形参名字 , 形式非常简单
  3. 声明对象类型的时候(多态)

下面要做一些拓展(两个层次的上下限):
  1. 类Box<T>中可以向T传入不同的类型参数。T作为形式参数(注意T是传入 类型名,(相当于Object啊),不是对象,这点很特殊,不是多态)
    1. 可以限制T的类型范围,在<T>中标记类型限定:
      1. 不管该限定是类还是接口,统一都使用关键字extends
      2. 跟类的继承使用的关键字是一样的,这里的特点是,这个关键字写在<>里
      3. 这里extends的意思是,T可以是他们的子类(不能是XX的父类。跟没节操的下面不一样)
      4. 可以使用&符号给出多个限定
      5. 如果限定既有接口也有类,那么类必须只有一个,并且放在首位置
      6. 比如 Box<T extends Object&Comparable&Serializable>
  2. 另一个层面(上面说的是Box<T> 中的T,下面要说有<T>这个尾巴的Box<T>本身) ,当【Box<T>这个类的对象】要【作为参数】进行传递的时候,用什么作为它的基类呢?(注意,这里就是传统的传递对象了,用基类和多态完成)
    1. 实验证明,Box<Fruit>和Box<Apple>之间没有等级关系,应该是都为Box类。但是这个Box基类要如何表示呢
    2. JAVA给了一种方法,Box<?>是Box<具体类型名>的基类,于是方法可以是这样:
      public static void getData(Box<?> data)
    3. 而且另一个层面,可以限制用Box<?>作为类型形参传入的Box<具体类型名>对象的范围,在形式参数Box<?>上标记通配符上下限:
      1. 注意点:为什么说另一个层面,因为在对 method(Box<?>  data) 这个整体来看时,它作为一个参数的类型的限定,跟普通的 method(Box data) 对比
        1. 普通的method(Box data) ,表示data的类型,只能是Box类型,或者是Box子类
        2. 而method(Box<?>  data),表示data的类型,只能是Box<各种>的类型,无他
        3. 同时在method(Box<?>  data)中加入了上下限,再缩小了【Box<各种>】的范围,变成【Box<上下限>】
      2. 具体用法:
        1. Box<? extends int>  ;意思是,可以传入以int的所有衍生类作为具体类型名参数的Box类型的对象(然后这个对象本身还可以传入多种不同的类型,也就是它有两重限制的样子)
        2. Box<? super int>;意思是,可以传入以int的所有父类作为具体类型名参数的Box类型的对象

Java泛型初探的更多相关文章

  1. 【Java心得总结三】Java泛型上——初识泛型

    一.函数参数与泛型比较 泛型(generics),从字面的意思理解就是泛化的类型,即参数化类型.泛型的作用是什么,这里与函数参数做一个比较: 无参数的函数: public int[] newIntAr ...

  2. 唬人的Java泛型并不难

    泛型 public interface Foo<E> {}public interface Bar<T> {}public interface Zar<?> {} ...

  3. Java泛型的历史

    为什么Java泛型会有当前的缺陷? 之前的章节里已经说明了Java泛型擦除会导致的问题,C++和C#的泛型都是在运行时存在的,难道Java天然不支持“真正的泛型”吗? 事实上,在Java1.5在200 ...

  4. 浅析Java 泛型

    泛型是JavaSE5引入的一个新概念,但是这个概念在编程语言中却是很普遍的一个概念.下面,根据以下内容,我们总结下在Java中使用泛型. 泛型使用的意义 什么是泛型 泛型类 泛型方法 泛型接口 泛型擦 ...

  5. Java:泛型基础

    泛型 引入泛型 传统编写的限制: 在Java中一般的类和方法,只能使用具体的类型,要么是基本数据类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制就会束缚很多! 解决这种限制的 ...

  6. java泛型基础

    泛型是Java SE 1.5的新特性, 泛型的本质是参数化类型, 也就是说所操作的数据类型被指定为一个参数. 这种参数类型可以用在类.接口和方法的创建中, 分别称为泛型类.泛型接口.泛型方法.  Ja ...

  7. 使用java泛型设计通用方法

    泛型是Java SE 1.5的新特性, 泛型的本质是参数化类型, 也就是说所操作的数据类型被指定为一个参数. 因此我们可以利用泛型和反射来设计一些通用方法. 现在有2张表, 一张user表和一张stu ...

  8. 关于Java泛型的使用

    在目前我遇到的java项目中,泛型应用的最多的就属集合了.当要从数据库取出多个对象或者说是多条记录时,往往都要使用集合,那么为什么这么使用,或者使用时有什么要注意的地方,请关注以下内容. 感谢Wind ...

  9. 初识java泛型

    1 协变数组类型(covariant array type) 数组的协变性: if A IS-A B then A[] IS-A B[] 也就是说,java中的数组兼容,一个类型的数组兼容他的子类类型 ...

随机推荐

  1. U3D教程宝典之两步实现超实用的XML存档

    两步实现超实用的XML存档 本套存档的优点:易使用,跨平台,防作弊(内容加密 + 防拷贝) 脚本下载地址 使用方法非常简单:把GameDataManager和XmlSaver两个脚本添加至工程后(1) ...

  2. 【LeetCode OJ】Swap Nodes in Pairs

    题目:Given a linked list, swap every two adjacent nodes and return its head. For example,Given 1->2 ...

  3. Windows内存放血篇,突破物理内存的CopyOnWrite

      本篇以x86(开启PAE) 以及x64 Win7系统 不借助微软API突破内存的写拷贝机制进行讲述 https://bbs.pediy.com/thread-222949.htm   0x01 B ...

  4. ThinkPHP5 封装邮件发送服务(可发附件)

    1.Composer 安装 phpmailer 1 composer require phpmailer/phpmailer 2.ThinkPHP 中封装邮件服务类 我把它封装在扩展目录 extend ...

  5. IOS设计模式第九篇之备忘录模式

    版权声明:原创作品,谢绝转载!否则将追究法律责任. 备忘录模式捕获和具体化对象的内部状态.换句话说,它可以节省你的东西后来,这种外部状态可以恢复在不违反封装; 也就是说,私人数据是私有的. 怎么用备忘 ...

  6. cxGrid数据录入

    一.数据录入 1 在TcxGridDBTableView中,设定属性 NewItemRow.Visible = True 2 在cxgrid中输入数据怎样回车换行   在TcxGridDBTableV ...

  7. Python六大开源框架对比:Web2py略胜一筹(转)

    Python是一门动态.面向对象语言.其最初就是作为一门面向对象语言设计的,并且在后期又加入了一些更高级的特性.除了语言本身的设计目的之外,Python标准库也是值得大家称赞的,Python甚至还自带 ...

  8. html2canvas - 微信中长按存图 - 将h5活动结果保存到本地

    现在有很多在微信里流行的h5活动页.这些小h5大部分都是简单的交互然后得出一个abcd早就拟定好的结果,根据你的选项分几种情况,最终得到其中一个作为你测试的答案.比如这个就是最后那张结果图: 当时自己 ...

  9. Openstack 在VMware虚拟机ESXI和Workstation下安装需要更改参数

    [vmware vsphere] 要在esxi 5i的系统文件/etc/vmware/config最后添加vhv.allow = “TRUE” 一行.重启 VMware ESXi 后编辑虚拟机选项(需 ...

  10. 总结一下最近用到的技术(1)--ultraESB

    最近项目中方法用到了一些新的东西,由于之前没有用到过,现在总结一下,方便以后查阅,本篇文章介绍ultraESB,接下来的文章会介绍JsonSchema,JsonSchamaValidator,Json ...