JAVA泛型的简单思考一

Wesley13
• 阅读 750

对于熟悉JAVA语言的coder来说,泛型绝对曾让自己伤透脑筋,因为java中的泛型就像是一个糖果,但嚼起来却痛苦不堪(可能有点过分,不过看很多论坛贴吧的抱怨,我觉得也是不可否认的)。每个初涉泛型的人可能都会经历这样的阶段,什么是泛型,为什么会有泛型,怎么样使用泛型,它能给我们带来什么?等等

      其实早在JDK1.5之前,java还不存在泛型,但java语言是强类型,编译型语言,而且我们强调要尽早的(编译期间)发现异常解决异常,然而没有泛型我们可能会遇到这样的问题:

            

List fruits = new ArrayList();
fruits.add(new Apple());
fruits.add(new Egg());
fruits.add(new People());
((Fruit) fruits.get(2)).juice();//it's horrible,and exception will be checked delaying runtime

      以上的代码告诉我们,在没有泛型时我们可以将任何的类型添加到一个水果篮中,但我们希望的只是水果,可此时编译器无法发现问题的所在,因为编译器对此毫无所知,你必须到运行时才能发现问题的所在,这可不是我们想要的结果。

为了避免这样的不爽,SUN 的工程师们从JDK1.5开始引进了泛型来解决一系列无法在编译器发现的类型问题,但将上面的代码通过泛型进行优化后我们会发现:

           

List<Fruit> fruits = new ArrayList <Fruit>();
fruits.add( new Apple());
fruits. add(new Egg());//bad fruit
fruits. add(new People());//bad fruit
fruits.get(0).juice();//it's fruit ,you can get juice

此时你只能将水果放入你的水果篮,因为这个水果篮是编译器强制要求的,我们通过这样的语法告诉编译器我们需要的是果篮而不是其他什么~!这样当你使用水果篮中的水果是你可以确切的知道,我拥有的是水果我可以榨取果汁。这就是泛型带给我们的,它可以确保我们的类型安全,我们不会再试图把一个People榨出果汁来,而编译器却毫无在乎。

可能你会好奇JAVA 是如何通过泛型来进行编译器的安全监察的,其实这只是编译器的一个小手段,它会透明的为我们进行类型的强制转换,而强制转换的依据便是你声明在尖括号中的类型。看一下编译后再反编译的的代码你就会明白了:

                   

List fruits = new ArrayList();
fruits.add(new Apple());
Fruit fruit = (Fruit)fruits.get(0);

你可能会有点失望,为什么还是类型装换,这跟我们自己做的有什么区别的,相信很多人都会抱怨,尤其是熟悉C++模板的coder。但我们也不能过于责备SUN的工程师们,因为这是为了兼容以前的JDK版本,为了让低版本中编写的代码依旧可以运行在支持泛型的JVM上,这是一个对用户负责的考虑。让我们来看一下编译器是怎么处理我们的泛型代码的:

当我们写好了一个泛型代码时,尖括号中的类型总是会通知编译器,我们需要的类型,编译器便会在需要类型安全的地方进行类型转化,而当他发现你使用的不是匹配类型时便会抛出一个编译时异常,而不需要等到运行时。

当然泛型并不只是在容器中使用(虽然这是应用最多的地方,尤其是对应用开发人员)但我们还有泛型类,泛型方法,泛型数组需要理解,不过中心思想还是上面讲到的这些,都是编译器把戏,我们需要了解的是为了达到一个目的,编译器做了什么,为什么这么做就足够了。

点赞
收藏
评论区
推荐文章
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
浪人 浪人
3年前
死磕Java泛型(一篇就够)
Java泛型,算是一个比较容易产生误解的知识点,因为Java的泛型基于擦除实现,在使用Java泛型时,往往会受到泛型实现机制的限制,如果不能深入全面的掌握泛型知识,就不能较好的驾驭使用泛型,同时在阅读开源项目时也会处处碰壁,这一篇就带大家全面深入的死磕Java泛型。泛型擦除初探相信泛型大家都使用过,所以一些基础的知识点就不废话了,以免显得啰嗦。
Wesley13 Wesley13
3年前
java 泛型详解
对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下。本文参考java泛型详解、Java中的泛型方法、java泛型详解1\.概述泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用。什么是泛型?为什么要使用泛型?泛型,即“参数化类型”。一提到参数,最熟
Wesley13 Wesley13
3年前
java泛型
一、实现机制java泛型实现方法为类型擦除,基于这种方法实现的泛型称为伪泛型。java泛型只在源代码中存在,在编译后的文件中替换为原生类型,并插入强制转换。(真正的泛型是应该存在于源码、编译后文件、运行期)二、擦除实例源码:List<StringtestListnewArrayList<String();
浪人 浪人
3年前
java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一
java泛型详解绝对是对泛型方法讲解最详细的,没有之一对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下。本文参考、、1、概述泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用。什么是泛型?
Stella981 Stella981
3年前
Gson通过借助TypeToken获取泛型参数的类型的方法
最近在使用Google的Gson包进行Json和Java对象之间的转化,对于包含泛型的类的序列化和反序列化Gson也提供了很好的支持,感觉有点意思,就花时间研究了一下。由于Java泛型的实现机制,使用了泛型的代码在运行期间相关的泛型参数的类型会被擦除,我们无法在运行期间获知泛型参数的具体类型(所有的泛型类型在运行时都是Object类型)。但是有的时候
Wesley13 Wesley13
3年前
Java泛型详解
引言Java泛型是jdk1.5中引入的一个新特性,泛型提供了编译时的类型检测机制,该机制允许程序员在编译时检测到非法的类型。泛型是Java中一个非常重要的知识点,在Java集合类框架中泛型被广泛应用。本文我们将从零开始来看一下Java泛型的设计,将会涉及到通配符处理,以及让人苦恼的类型擦除。泛型基础
Easter79 Easter79
3年前
Thinking in java Chapter15 泛型
1与C比较2简单泛型泛型类3泛型接口4泛型方法5匿名内部类6构建复杂模型78910“泛型”意思就是:适用于许多许多的类型<h2id"1"1与C比较</h2C
Wesley13 Wesley13
3年前
Java的泛型详解(一)
Java的泛型详解(一)编写的代码可以被不同类型的对象所重用。因为上面的一个优点,泛型也可以减少代码的编写。1|2泛型的使用简单泛型类publicclassPair{privateTfirst;privateTsecond;publicPair(){firstnull;secondnull;
Wesley13 Wesley13
3年前
Java 进阶巩固:深入理解 泛型
首先提个问题:Java泛型的作用是什么?泛型擦除是什么?泛型一般用在什么场景?如果这个问题你答不上来,那这篇文章可能就对你有些价值。读完本文你将了解到:什么是泛型(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fblog.csdn.net