JAVA泛型的简单思考一

对于熟悉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

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

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

                   

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

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

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

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

点赞
收藏

评论区

加载中...

相关推荐

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java 泛型详解

对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下。本文参考java泛型详解、Java中的泛型方法、java泛型详解1\.概述泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用。什么是泛型?为什么要使用泛型?泛型,即“参数化类型”。一提到参数,最熟

java泛型

一、实现机制java泛型实现方法为类型擦除,基于这种方法实现的泛型称为伪泛型。java泛型只在源代码中存在,在编译后的文件中替换为原生类型,并插入强制转换。(真正的泛型是应该存在于源码、编译后文件、运行期)二、擦除实例源码:List<StringtestListnewArrayList<String();

死磕Java泛型(一篇就够)

Java泛型,算是一个比较容易产生误解的知识点,因为Java的泛型基于擦除实现,在使用Java泛型时,往往会受到泛型实现机制的限制,如果不能深入全面的掌握泛型知识,就不能较好的驾驭使用泛型,同时在阅读开源项目时也会处处碰壁,这一篇就带大家全面深入的死磕Java泛型。泛型擦除初探相信泛型大家都使用过,所以一些基础的知识点就不废话了,以免显得啰嗦。

java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一

java泛型详解绝对是对泛型方法讲解最详细的,没有之一对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下。本文参考、、1、概述泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用。什么是泛型?

Gson通过借助TypeToken获取泛型参数的类型的方法

最近在使用Google的Gson包进行Json和Java对象之间的转化,对于包含泛型的类的序列化和反序列化Gson也提供了很好的支持,感觉有点意思,就花时间研究了一下。由于Java泛型的实现机制,使用了泛型的代码在运行期间相关的泛型参数的类型会被擦除,我们无法在运行期间获知泛型参数的具体类型(所有的泛型类型在运行时都是Object类型)。但是有的时候

JAVA泛型的简单思考一 - HelloWorld