Java泛型初探
- 泛型就是参数化类型,一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参,其实你回味一下这里。形参参数化的是变量的值,而如果你想参数化变量的类型,那就用到泛型了。同样的, 定义的时候叫类型形参,使用时传入类型实参
- 所以很多时候你会遇到,定义一个方法的时候,形参的类型和值都是用变量表示的,比如:<T> T[] toArray(T[] a);
- 所以 , 泛型就是把类中或者方法中某些数据的类型也作为参数来传递,使得代码更加灵活
- 对比:
- 我把以前的做:参数化变量、变量形参、变量实参
- 现在的叫做:参数化类型、类型形参、类型实参
- 其实两个还有很大区别的:
- 参数化变量只在定义方法的时候会使用,对类没有参数化变量一说,实例化类传递的参数实际上只是构造方法的参数
- 而参数化类型不仅在定义方法的时候使用,还在定义类的时候会使用到,这点上它会带来很大的不同
- 参数化类型能通过形式参数限定实际参数范围。类比参数化变量,是这样的样子:比如变量类型是Int,你要求int的范围是0到100,于是有 int<100> a;
- 本来类之间的相对关系只有一个维度(虽然类似是一个树图),两个类之间有明确的上下关系或者是没有关系(即使算上多重继承),但如果一个类又有了参数化类型的尾巴的话,那类之间的关系又有了一个新的维度,造成的结果可能是这个维度上,A在上B在下,而在另一个维度,B在上A在下,不过目前JAVA就规定尾巴的维度不使用
- 这里可能对于尾巴这个维度有一点异议,因为它比较复杂
- 在定的时候,一般如果是<T>,那这个维度可以说没有,但如果对这个T有extends的话,那确实会有一个范围,会有一个上下关系
- 在使用的,这种上下关系就很明显了,T本身的取值就是类型,它的上下关系会造成外面 Class<T>的上下关系吗
- 这里可能对于尾巴这个维度有一点异议,因为它比较复杂
- 对类的使用场景有:定义类的时候,实例化类的时候,声明对象类型的时候(多态)
- 前两种情况比较简单,但是第三种情况就需要实际面临上面提到的问题【在使用的,这种上下关系就很明显了,T本身的取值就是类型,它的上下关系会造成外面 Class<T>的上下关系吗 】,你需要找到一个基类
- 实例化泛型类的时候需要显式传递泛型参数,使用泛型方法则一般通过参数传递
- 定义泛型时(定义泛型时只能发生在 类/接口的定义 和方法的定义时)
- 定义泛型--类/接口,就是在定义类的时候指定某个类型为参数。形式是这样,<>写在定义的类的名称的后边: class Box<T> { .......}
- 定义泛型--方法,就是在定义方法的时候指定某个类型为参数。形式是这样,<>写在方法的public 后 void前:public <T> T[] toArray(T[] a);
- 使用泛型时
- 使用泛型可以发生在 任何时候,包括 类/接口的定义 和方法的定义时
- 使用方法就是把本来应该写类型名称的位置改成你定义的泛型形参名字 , 形式非常简单
- 声明对象类型的时候(多态)
- 类Box<T>中可以向T传入不同的类型参数。T作为形式参数(注意T是传入 类型名,(相当于Object啊),不是对象,这点很特殊,不是多态)
- 可以限制T的类型范围,在<T>中标记类型限定:
- 不管该限定是类还是接口,统一都使用关键字extends
- 跟类的继承使用的关键字是一样的,这里的特点是,这个关键字写在<>里
- 这里extends的意思是,T可以是他们的子类(不能是XX的父类。跟没节操的下面不一样)
- 可以使用&符号给出多个限定
- 如果限定既有接口也有类,那么类必须只有一个,并且放在首位置
- 比如 Box<T extends Object&Comparable&Serializable>
- 可以限制T的类型范围,在<T>中标记类型限定:
- 另一个层面(上面说的是Box<T> 中的T,下面要说有<T>这个尾巴的Box<T>本身) ,当【Box<T>这个类的对象】要【作为参数】进行传递的时候,用什么作为它的基类呢?(注意,这里就是传统的传递对象了,用基类和多态完成)
- 实验证明,Box<Fruit>和Box<Apple>之间没有等级关系,应该是都为Box类。但是这个Box基类要如何表示呢
- JAVA给了一种方法,Box<?>是Box<具体类型名>的基类,于是方法可以是这样:
public static void getData(Box<?> data) - 而且另一个层面,可以限制用Box<?>作为类型形参传入的Box<具体类型名>对象的范围,在形式参数Box<?>上标记通配符上下限:
- 注意点:为什么说另一个层面,因为在对 method(Box<?> data) 这个整体来看时,它作为一个参数的类型的限定,跟普通的 method(Box data) 对比
- 普通的method(Box data) ,表示data的类型,只能是Box类型,或者是Box子类
- 而method(Box<?> data),表示data的类型,只能是Box<各种>的类型,无他
- 同时在method(Box<?> data)中加入了上下限,再缩小了【Box<各种>】的范围,变成【Box<上下限>】
- 具体用法:
- Box<? extends int> ;意思是,可以传入以int的所有衍生类作为具体类型名参数的Box类型的对象(然后这个对象本身还可以传入多种不同的类型,也就是它有两重限制的样子)
- Box<? super int>;意思是,可以传入以int的所有父类作为具体类型名参数的Box类型的对象
- 注意点:为什么说另一个层面,因为在对 method(Box<?> data) 这个整体来看时,它作为一个参数的类型的限定,跟普通的 method(Box data) 对比
Java泛型初探的更多相关文章
- 【Java心得总结三】Java泛型上——初识泛型
一.函数参数与泛型比较 泛型(generics),从字面的意思理解就是泛化的类型,即参数化类型.泛型的作用是什么,这里与函数参数做一个比较: 无参数的函数: public int[] newIntAr ...
- 唬人的Java泛型并不难
泛型 public interface Foo<E> {}public interface Bar<T> {}public interface Zar<?> {} ...
- Java泛型的历史
为什么Java泛型会有当前的缺陷? 之前的章节里已经说明了Java泛型擦除会导致的问题,C++和C#的泛型都是在运行时存在的,难道Java天然不支持“真正的泛型”吗? 事实上,在Java1.5在200 ...
- 浅析Java 泛型
泛型是JavaSE5引入的一个新概念,但是这个概念在编程语言中却是很普遍的一个概念.下面,根据以下内容,我们总结下在Java中使用泛型. 泛型使用的意义 什么是泛型 泛型类 泛型方法 泛型接口 泛型擦 ...
- Java:泛型基础
泛型 引入泛型 传统编写的限制: 在Java中一般的类和方法,只能使用具体的类型,要么是基本数据类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制就会束缚很多! 解决这种限制的 ...
- java泛型基础
泛型是Java SE 1.5的新特性, 泛型的本质是参数化类型, 也就是说所操作的数据类型被指定为一个参数. 这种参数类型可以用在类.接口和方法的创建中, 分别称为泛型类.泛型接口.泛型方法. Ja ...
- 使用java泛型设计通用方法
泛型是Java SE 1.5的新特性, 泛型的本质是参数化类型, 也就是说所操作的数据类型被指定为一个参数. 因此我们可以利用泛型和反射来设计一些通用方法. 现在有2张表, 一张user表和一张stu ...
- 关于Java泛型的使用
在目前我遇到的java项目中,泛型应用的最多的就属集合了.当要从数据库取出多个对象或者说是多条记录时,往往都要使用集合,那么为什么这么使用,或者使用时有什么要注意的地方,请关注以下内容. 感谢Wind ...
- 初识java泛型
1 协变数组类型(covariant array type) 数组的协变性: if A IS-A B then A[] IS-A B[] 也就是说,java中的数组兼容,一个类型的数组兼容他的子类类型 ...
随机推荐
- [OSX] 使用 MacPorts 安装 Python 和 pip 指南
Mac OS 未预装任何在 Unix/Linux 中常见的命令行包管理工具,Mac OS 中的 App Store 和自身的软件升级功能可以下载更新许多比较好的应用,但这些应用多数是满足普通消费者需求 ...
- Oracle和Mysql中mybatis模糊匹配查询区别
1.Oracle AND NAME LIKE '%'||#{name}||'%' 2.Mysql AND NAME LIKE "%"#{name}"%"
- Eclipse警告:The serializable class XXX does not declare a static final serialVersionUID field of type long
serialVersionUID作用: 序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性. 在Eclipse中可以自动生成,有两种生成方式: 一个是默认的1L,比如:privat ...
- (转载)Recyclerview | Intent与Bundle在传值上的区别 | 设置布局背景为白色的三种方法
用Recyclerview实现列表分组.下拉刷新以及上拉加载更多 http://www.jianshu.com/p/be62ce21ea57 Intent与Bundle在传值上的区别http://b ...
- 【转载】C#调用C++ DLL
using System; using System.Collections.Generic; using System.Linq; using System.Text; //1. 打开项目“Tzb” ...
- 在centos7 ubuntu15.04 上通过bosh-lite 搭建单机环境cloudfoundry
Bosh-lite简介 bosh-lite 是一个单机部署cloudfoundry的实验性工具,用于开发人员做poc 验证.Bosh-lite目前支持仅MAC OS X和Linux系统.B ...
- css修改select默认样式
先来看看效果图: css: <style media="screen"> .select_demo, .select_list { width: 400px; heig ...
- Twig---的使用
使用Twig的参考文档: https://www.kancloud.cn/yunye/twig-cn/159454 Twig是一款灵活.快速.安全的PHP模板引擎. 示例: <?php echo ...
- vue--获取监听获取radius的改变
做一个考试系统,单选题都是后台来的数据,所以一时间没有想到 @change这个方法: <template> <div id="Home"> <v-he ...
- HBase一次客户端读写异常解读分析与优化全过程(干货)
大数据时代,HBase作为一款扩展性极佳的分布式存储系统,越来越多地受到各种业务的青睐,以求在大数据存储的前提下实现高效的随机读写操作.对于业务方来讲,一方面关注HBase本身服务的读写性能,另一方面 ...