java 泛型精解

其实关于这块知识大概两年以前就有了个比较全的了解了吧,重新整理一下用自己的话写出来又是一次加深理解的过程。下面我大概会分三个方面去讲泛型,1、泛型的主要相关特性 2、怎么用泛型 3、泛型总结

1、泛型的主要相关特性

背景介绍:

Java泛型(generics)是JDK 5中引入的一个新特性,允许在定义类和接口的时候使用类型参数(type parameter)。声明的类型参数在使用时用具体的类型来替换。泛型最主要的应用是在JDK 5中的新集合类框架中。对于泛型概念的引入,开发社区的观点是褒贬不一。从好的方面来说,泛型的引入可以解决之前的集合类框架在使用过程中通常会出现的运行时刻类型错误,因为编译器可以在编译时刻就发现很多明显的错误。而从不好的地方来说,为了保证与旧有版本的兼容性,Java泛型的实现上存在着一些不够优雅的地方。当然这也是任何有历史的编程语言所需要承担的历史包袱。后续的版本更新会为早期的设计缺陷所累。

a、类型擦除

正确理解泛型概念的首要前提是理解类型擦除(type erasure)。 Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节代码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会被编译器在编译的时候去掉。这个过程就称为类型擦除。还是上例子吧,如下:


泛型擦除导致编译不通过

按照我们对于重载的理解,方法参数类型不一样应该是可以定义的啊,这个理论一直是成立的。主要原因是在于泛型是在编译的时候类型会擦除,这样两个方法的参数类型都是List,是不带参数的噢。所以重载不通过导致编译不通过。

b、泛型在初始化、实例化的时候需要知道确切的类型

泛型在没有申明具体的类型的时候是不能进行实例化,因为它在此时只是一个代号,换句话说我创建一个对象的过程要经历,加载、连接、初始化、实例化。我连你的基本信息都不知道我怎么进行下去啊,上例子,如下:


泛型不知道具体类型初始化编译不通过

这种情况下new T()编译失败。

c、泛型和子类型

我们知道在java中存在 父类  a = new 子类(); 这种写法是成立的而且是一个比较好的写法。但是List<父类> list = new ArrayList<子类>(); 这种写法会成立吗,事实是没有成立编译会报错,上例子:


泛型和子类型转换关系

为什么会这样呢,应该这么理解如果这种写法成立的话,那我fruits就可以add  Child2、Child3等其他子类了。

到时候我从fruits里面取出来集合里面的元素的时候我应该转换成Child、Child2、Child3 ??? 编译器也不知道啊。

d、泛型通配符

我想在通配符这个点我会多讲一点。

d1、通配符?

这里使用了通配符?指定可以使用任何类型的集合作为参数。读取的元素使用了Object类型来表示,这是安全的,因为所有的类都是Object的子类。这里就又出现了另外一个问题,如下代码所示,如果试图往使用通配符?的集合中加入对象,就会在编译时出现错误。需要注意的是,这里不管加入什么类型的对象都会出错。这是因为通配符?表示该集合存储的元素类型未知,可以是任何类型。往集合中加入元素需要是一个未知元素类型的子类型,正因为该集合存储的元素类型未知,所以我们没法向该集合中添加任何元素。唯一的例外是null,因为null是所有类型的子类型,所以尽管元素类型不知道,但是null一定是它的子类型。另一方面,我们可以从List lists中获取对象,虽然不知道List中存储的是什么类型,但是可以肯定的是存储的类型一定是Object的子类型,所以可以用Object类型来获取值。如for(Object obj: lists),这是合法的。

还是上代码:


通配符?样例代码

d2、?extends通配符

其实这个也好理解,可以理解为某个接口或者某个抽象类的所有实现类,上例子:


?extends Serializable使用

List<? extends Serializable> 中存放的是所有的Serializable的实现类,如可能是String、Integer等

我们在取出来的时候就可以转换成Serializable ,但是我们还是不能往里面add元素原因跟上面通配符 ?一样

d3、?super通配符

这里还有一种边界通配符为?super,可以表示当前类或者当前类的父类,还是上例子吧:

?super通配符使用

e、泛型的推断

自Java SE 7起, 你可以使用一个空的类型参数集合 (<>)代替构造器的参数化类型:Map<String, List> myMap = new HashMap<>();注意:想要在泛型类初始化期间利用自动类型推断。

2、怎么用泛型

上面主要介绍了一些泛型的主要特性吧,下面我还是想说说怎么使用泛型吧。

泛型用自己的话来说就是“参数化类型”,在各种实体类型的基础上抽象出一个虚拟的类型,你可以叫A、B、C、T等。

具体的使用可以有两种比较常见的表现形式,类泛型 、方法泛型

a、类泛型

从字面上理解为你定义的泛型是整个类通用的或者是类里面所有的泛型类型就引用类上的自己方法上不额外定义,例子如下:


类泛型定义
类泛型实现

从上面可以看出类中定义了请求类型为Request返回类型为Response这个为了可读性强一点这么定义,在process抽象方法中直接用Request,Response来表示方法所需要的类型。

在实现类中就可以用具体的String、Integer代替接口中申明的泛型类型。

b、方法泛型

方法泛型我感觉就没类泛型那么抽象性高,可以为每一个方法来独自定义自己的类型了,上例子:

方法泛型实现


如上是一个简单的将List 里面的实体用某个字段作为key转换到Map中,中间的转换过程TODO.

方法上应用了K,V两个类型,但是这两个类型是需要申明定义的,所以在方法修饰符后面要自定义一下类型,如果不定义<K,V>是要编译出错的。

3、泛型总结

上面1、2部分介绍了泛型的一些主要特性和常用用法以后,我们对于泛型的认识应该是比较清晰的,所有的哪怕是泛型的复杂应用都是从上面讲的一些演变过来了,其实挺简单的。什么时候用泛型这个需要自己去思考?总之我觉得能够抽象出一个统一的类型就可以用。。。

3 Q very much!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,478评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,825评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,482评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,726评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,633评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,018评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,168评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,320评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,264评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,288评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,995评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,587评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,909评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,284评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,862评论 2 339

推荐阅读更多精彩内容

  • object 变量可指向任何类的实例,这让你能够创建可对任何数据类型进程处理的类。然而,这种方法存在几个严重的问题...
    CarlDonitz阅读 904评论 0 5
  • 开发人员在使用泛型的时候,很容易根据自己的直觉而犯一些错误。比如一个方法如果接收List作为形式参数,那么如果尝试...
    时待吾阅读 1,034评论 0 3
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,125评论 9 118
  • 上午回姥娘家。小姑娘自己选择要穿那件粉色的长袖公主裙。想到接下来几乎所以的日子都要穿那身肥大,没有性别区分的校服,...
    海阔林韵阅读 112评论 0 0
  • 我们的这座小城虽然地方不大,书店却不少,单单新华书店就有两个,其他知名、不知名的小书店更是多如牛毛。当然,若论藏书...
    辰辰的爸爸阅读 291评论 4 0