目录放在这里太长了,附目录链接大家可以自由选择查看——–Java学习目录
目录,更新ing,学习Java的点滴记录
为什么要使用泛型
一般的类和方法,只能使用具体的类型:要么是基本类型要么是自定义类.如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大
多态
算是一种泛化机制.例如,你可以将方法的形参类型设为基类
,那么该方法就可以接受从这个基类导入的任何类作为参数.这样的方法更加通用,应用场合也比较多.在类的内部也是如此,凡是需要说明类型的地方,如果都使用基类,确实能够具备更好地灵活性.接口
,而不是具体的类,这种限制又放松了很多.因为任何实现了该接口的类都能够满足该方法.泛型
.泛型实现了参数化类型
的概念,使代码可以应用于多种类型.“泛型”这个术语的意思是”适用于许许多多的类型”.并且在你创建一个参数化类型的实例时,编译器会为你负责转型操作,并且保证类型的正确性
.泛型对于集合类尤其有用
泛型意味着编写的代码可以被很多不同类型的对象所重用
简单泛型的使用
但是该类的重用性就很差了,只能持有一种类型的对象
现在的Genericity可以存储任何类型的对象.但是获取值的时候必须强制类型转换用来指定容器要持有什么类型的对象
,而且由编译器来保证类型的正确性.类型参数
,用尖括号扩住,放在类名后面.在使用这个类的时候,再用实际的类型替换此类型参数.类型参数的魅力在于:使得程序具有更好的可读性和安全性
这样以后创建Genericity对象,必须指明想要持有什么类型的对象,将其置于尖括号内.以后,你就只能在Genericity中存入该类型机及其子类(因为多态和泛型不冲突)
,并且在取出对象时,会自动进行类型转换.
Java7之后的版本就可以在构造函数中省略泛型参数了,如上图main中第一行,编译器也可以很好的利用这个信息,调用get时,不需要类型转换,编译器就知道返回值类型为Car.核心概念
:告诉编译器想使用什么类型,然后编译器帮你处理一切细节定义泛型类
具有一个或多个类型参数的类
.
指定方法的返回值类型以及域和局部变量的类型
类型参数使用大写形式,且比较短.
在Java类库中,使用变量E表示集合的元素类型,K和V分别表示键与值类型.T(需要时可以选择U和S)表示"任意类型"
定义泛型方法
是否拥有泛型方法,与其所在的类是否是泛型没有关系
无论何时,就应该尽量使用泛型方法,也就是说,如果使用泛型方法可以取代将整个类泛型化,就应该只用泛型方法
.只需要将类型参数放在方法返回值之前即可
在该例子中,类并不是泛型化的,只有方法test具有类型参数,这也是由该方法的返回类型前面的类型参数指明的
当使用泛型类的时候,必须在创建对象的时候指定类型参数的值,而使用泛型方法的时候,通常不必指定参数类型,因为比那一起会为我们找出具体的类型,这称为类型参数推断
.因此,我们可以像调用普通方法一样调用test(),看上去test()被无限次重载过.并且调用test(0时传入基本类型
,自动打包机制就会介入其中,将基本类型的值包装为对应的对象.定义泛型接口
1) 该接口的实现类在定义时指定T类型
2) 实现类在定义时,如果不指定泛型T的类型,那么该实现类也必须是泛型类,最终类型决定取决于创建该实现类对象的时候去指定
类型参数的限定
分析一下代码,方法接收的形参是一个T类型的数组,首先对数组进行判断,看是否为null或者空数组,其次将数组第一个元素赋值给T类型的small,最后通过一个for循环遍历所有元素,在调用small的compareTo方法去比较大小,每次将最小值赋值给small,再将small返回,看似没有什么问题?仔细一想,T类型是不固定的,那么它一定持有compareTo方法吗?当然是不一定,这里就是问题点
解决方法就是:对类型参数加以限定,使之必须要满足一定条件
,这里将T限制为实现了Comparable接口的类
T implements Comparable
却使用了extends关键字,在之前的学习中显然extends是用来表示继承关系的.在下面这种记法中(T extends BoundingType),表示T应该是绑定类型的子类型.T和绑定类型可以是类也可以是接口.选择extends关键字的原因是更接近与子类的概念.
类型擦除
原始类型
.
原始类型的类名字就是删去类型参数后的泛型类的类名
.
擦除类型参数,如果有进行类型限定
的话,就替换为限定类型中的第一个(因此可以对一个T进行多个类型限定),无限定的变量用Object,看文字可能不明白,下面给出两个例子,一个未进行类型限定,一个进行了类型限定
泛型类
对应原始类
泛型类
原始类型
一开始我个人理解也是ArrayList与ArrayList很容易被认为是不同的类型,因为传递的泛型都不一样,但是上面的程序会认为他们是相同的类型
一个残酷的现实就是:在泛型代码内部,无法获得任何有关泛型参数类型的信息---无法知道用来创建某个特定实例的实际的类型参数
.擦除
来实现的,这意味着当你使用泛型时,任何具体的类型信息都被擦除了,你唯一知道的就是你在使用一个对象,因此List和List在运行时事实上都是相同的类型,这两种类型都被擦除
为他们的原生类型—List.约束与局限性(两个常见的)
不能用类型参数代替基本类型.因此,没有Pig,只有Pig.原因就是类型擦除.擦除之后,Pig类含有Object类型的域,而Object不能存储double值.
虚拟机中的对象总有一个特定的非泛型类型.因此,所有的类型查询只产生原始类型.比如:
通配符类型
T表示某个具体的类型,?表示不确定的Java类型无界通配符在方法中声明形参时比较重要
从代码中可以发现,runOne方法只能接受泛型为Animal类型的参数,而runTwo使用了无界通配符,可以接收所有类型作为参数,更加灵活
所以,对于不确定的类型或者某个类的继承结构中的子类的类型,可以使用无界通配符 ,表示可以持有任何类型。在runTwo方法中,使用了?之后就不会关心具体传入的参数了
extends:参数化的类型可能是所指定的类型,或者是此类型的子类
使用了extends的位置,可以传递Animal或者其任何子类的参数,并且,extends指定的上界可以有多个,中间用逗号分开
super
:表示参数化的类型可能是所指定的类型,或者是此类型的父类型,直至 Object
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算