java 1.8 泛型_Java基础泛型的介绍 泛型是一种仅存于编译期间的神奇的东西

面向对象的一个重要目标是对代码重用的支持,在JDK5新增了一个机制泛型,泛型也是我们使用想当频繁的,尤其是用于对容器、集合对其内部元素的约束。那我们泛型是怎么样实现的呢,在java中泛型的思想就是如下图所示,我们通过简单的代码实现意义上的泛型。

50258af1e6c1bdb6a78acbfdc55d1a68.png

如该图中,我们借助Object这种顶级超类来实现一个简单的泛型,将任意的一个传入参数写入write方法,再通过read取出,它的值发生改变了吗?没有,那么它的类型变了吗,变了,在这里是变成Object,而实际上我们可以通过反射来动态获取泛型T的类型,那么这时返回的就一定是你在<>中指定的类型了。看到这里大家明白为什么泛型只是一种编译期的约束了吧,并不是太玄幻的东西,而是我们使用Java也可以实现的。

我们在使用泛型时需要考虑两点,一个是我们对该类取出storedValue时需要进行类型转换,因为参数是作为Object被接收的,取出去时需要转换成相应的类型。第二点就是Object不兼容数字,Boolean等基本类型,所以我们需要对基本类型进行封装,这种封装之后的类叫做包装类,在框架中会经常用到。我们可以自定义一个包装类,也可以直接使用JDK提供的Integer这种包装类。

那么我们怎样在接口中使用泛型呢,大多集合都具备一个方法, compareTo,它们大多实现了Comparable接口

9253c7c84b848035181dc23fd2813788.png

该接口就用到了泛型来对子类容器中元素进行约束。为什么要这么做呢,因为compareTo方法用于比较容器元素的大小,那么我如果不约束容器中元素类型,要怎么比较int类型和Object类型的大小呢?下面我们自己手写Comparable的实现类,来了解一下泛型在接口中的应用。

06b645b1b2998ccae1d34b61c518d4a0.png

这是一个普通java类用来充当数组中的元素,它实现了Comparable接口,实现该接口就要重写compareTo方法,该方法用于定义不同情况下的大小比较规则, 本次使用简单的int类型来比较大小。

2fe2e0b4996d64c9e6c24a371608ed4d.png

这是一个小算法,该算法使用一个index储存元素最大值的下标,遍历整个数组每次调用compareTo方法,如果返回值>0则更新元素最大值下标,这样一来遍历结束后index一定就是数组中元素最大值的下面。这个例子在正常情况下是可以执行成功的,首先findMax方法内参数一定是Comparable接口的子类这个毫无疑问,但是加入有另一个元素String,或者类XX,他们虽然都实现了Comparable接口,但是对比较的规则可能会有出入,这样一来在我们比较数组元素最大值时就不能保证它的准确性,以及我们期望的目的。需要一个东西对Comparable数组内元素有一个约束,泛型就刚好用得上。

f7b53bac372fecbdc66033bea3bfa29a.png

我们使用泛型来保证数组内元素一定为Aoo及其子类,再对Aoo使用final修饰防止其子类重写比较规则那么这样一来就能够保证findMax方法达到预期的效果。与泛型同期处于JDK1.5更新的还有一个叫做自动拆箱和自动装箱的概念,就是为了使泛型能够兼容基本数据类型,JDK提供了它们的包装类,而我们常用的1,1.5这种数字默认类型还是int和double,需要将int转成Integer类型,而1.5以后的版本jvm会自动调用Integer的构造方法,将1转成Integer。同理,如果在需要使用int类型的地方你传入了Integer,jvm也会自动将其转型成Integer,这就是自动拆装箱。下面看一下泛型的具体使用方法

f679b9526390d4352a84689760c62bf2.png

可以在类或者接口名旁边通过尖括号声明泛型,可以把T,FD,B红框中的当做占位符,我们在使用该类时要求传入泛型,那时候T,FD,B将会被我们传入的泛型替换掉。在JDK1.8版本中带有泛型的方法不可以再指明泛型类型,由JVM自行推断实际类型。由于泛型也是一个对象,那么它一定支持继承。在Java中一定要把所有东西都当做对象,我们可以这样写,该约束表明传入的类型一定是Father以及它的子类,则表明需要传入泛型为Father,以及它的父类。也有另外一种写法>,?是一个通配符,他与T功能相同但是?是只读的,什么意思呢?在代码运行期间T这种泛型可以被动态修改,而?不可以。

类型擦除是编译期将泛型类转变成原始类,去如何擦出的呢?编译器生成与泛型类同名的原始类,原始类中的泛型会被替换为Object如果有,,这种对泛型的限定则被替换为Father类型。为什么要对泛型进行擦除呢,因为泛型并不是真正意义上的泛型,因为泛型类无法被编译成class文件,因此它的生命周期仅存于编译期间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值