java泛型类和泛型方法

JAVA学习网 2020-11-17 12:44:04

《Java编程思想》第四版足足用了75页来讲泛型——厚厚的一沓内容,很容易让人头大——但其实根本不用这么多,只需要一句话:我是一个泛型队列,狗可以站进来,猫也可以站进来,但最好不要既站猫,又站狗!

01、泛型是什么

泛型,有人拆解这个词为“参数化类型”。这种拆解其实也不好理解,还是按照沉默王二的意思来理解一下吧。

现在有一只玻璃杯,你可以让它盛一杯白开水,也可以盛一杯二锅头——泛型的概念就在于此,制造这只杯子的时候没必要在说明书上定义死,指明它只能盛白开水而不能盛二锅头!

可以在说明书上指明它用来盛装液体,但最好也不要这样,弄不好用户想用它来盛几块冰糖呢!

这么一说,你是不是感觉不那么抽象了?泛型其实就是在定义类、接口、方法的时候不局限地指定某一种特定类型,而让类、接口、方法的调用者来决定具体使用哪一种类型的参数。

就好比,玻璃杯的制造者说,我不知道使用者用这只玻璃杯来干嘛,所以我只负责造这么一只杯子;玻璃杯的使用者说,这就对了,我来决定这只玻璃杯是盛白开水还是二锅头,或者冰糖。

02、什么时候用泛型

我们来看一段简短的代码:

这段代码的意思是:我们在map中放了一只狗(Dog),又放了一只猫(Cat),当我们想从map中取出猫的时候,却一不留神把狗取了出来。

这段代码编译是没有问题的,但运行的时候就会报ClassCastException(狗毕竟不是猫啊):

Exception in thread "main" java.lang.ClassCastException: com.cmower.java_demo.sixteen.Cmower$Dog cannot be cast to com.cmower.java_demo.sixteen.Cmower$Cat

at com.cmower.java_demo.sixteen.Cmower.main(Cmower.java:20)

 

为什么会这样呢?

1)写代码的程序员粗心大意。要从map中把猫取出来,你不能取狗啊!

2)创建map的时候,没有明确指定map中要放的类型。如果指定是要放猫,那肯定取的时候就是猫,不会取出来狗;如果指定是要放狗,也一个道理。

第一种情况不太好解决,总不能把程序员打一顿(我可不想做一个天天背锅的程序员,很重的好不好);第二种情况就比较容易解决,因为Map支持泛型(泛型接口)。

注:在Java中,经常用T、E、K、V等形式的参数来表示泛型参数。

T:代表一般的任何类。
E:代表 Element 的意思,或者 Exception 异常的意思。
K:代表 Key 的意思。
V:代表 Value 的意思,通常与 K 一起配合使用。

既然Map支持泛型,那作为Map的实现者HashMap(泛型类)也支持泛型了。

其中的put方法(泛型方法)是这样定义的:

好了,现在使用泛型的形式来定义一个只能放Cat的Map吧!

当使用泛型定义map(键为String类型,值为Cat类型)后:

1)编译器就不再允许你向map中添加狗的对象了。

2)当你从map中取出猫的时候,也不再需要强制转型了。

03、类型擦除

有人说,Java的泛型做的只是表面功夫——泛型信息存在于编译阶段(狗队在编译时不允许站猫),运行阶段就消失了(运行时的队列里没有猫的信息,连狗的信息也没有)——这种现象被称为“类型擦除”。

来,看代码解释一下:


PS:如果大家在学习过程中遇到什么问题,或者缺乏相关的学习资料,可查看我的公告栏获取,有问题随问随答,还有我这段时间整理的一些Java学习手册,面试题,开发工具,PDF文档书籍教程,需要的话都可以免费分享给大家。

 

阅读(2427) 评论(0)