深入java 认识泛型及其用法
来源:互联网 发布:qq飞车紫焰战神数据 编辑:程序博客网 时间:2024/05/29 08:54
这篇文章转载java序列化和反序列化过程中,值得注意的一些细节问题。更多的源代码请访问我的github:https://github.com/yangsheng20080808/deepIntoJava
本文分为4大部分
- 我们为什么需要泛型
- 泛型类和自定义泛型类
- 泛型方法和自定义泛型方法
我们为什么需要泛型
在jdk1.5之前,我们想要在一些集合中添加同类的元素,一般是怎么做呢?只能通过
1. Object 是所有类型的父类
2. 类型强制转换
这两个特点的配合来实现泛型的功能,这样实现的泛型功能要在程序运行期才能知道 Object 真正的对象类型,在 javac 编译期,编译器无法检查这个 Object 的强制转型是否成功,这便将一些风险转接到了程序运行期中,很有可能会出现:ClassCastException(类型转化错误。)
我们举例子说明:
但是该错误只能在运行期间才能发现,程序能够正常的通过编译,并不会报错。其实我们应该尽快通知程序员。
泛型是一种语法糖,它出现可以确保集合类安全的使用和改正集合类的类型安全弱点。(关于什么是语法糖我们可以见下方)
语法糖(Syntactic Sugar),也称糖衣语法,是由英国计算机学家 Peter.J.Landin 发明的一个术语,指在计算机语言中添加的某种语法。 目标:这种语法对语言的功能并没有影响,但是更方便程序员使用。Java 中最常用的语法糖主要有泛型、变长参数、条件编译、自动拆装箱、内部类等。 JVM虚拟机并不支持这些语法,它们在编译阶段就被还原回了简单的基础语法结构,这个过程成为解语法糖。
java在jdk1.5之后,引入的泛型实际上只在程序源码(我们的java文件)中存在,在编译后的字节码文件(编译后得到的class文件)中,就已经被替换为了原来的原生类型,并且在相应的地方插入了强制转型代码,因此对于运行期的Java语言来说,ArrayList和 ArrayList就是同一个类。所以泛型技术实际上是 Java 语言的一颗语法糖,Java 语言中的泛型实现方法称为类型擦除,基于这种方法实现的泛型被称为伪泛型。
举个例子说明:
我们用idea自带的反编译工具反编译的结果是:
集合在声明的时候类型被替换为了原来的原生类型,并且在相应的地方插入了强制转型代码
用了泛型后假如我们想加入别的类型,在编译器就会报错
泛型最主要的优点就是让编译器追踪参数类型,执行类型检查和类型转换:编译器保证类型转换不会失败。
如果依赖程序员去追踪对象类型和执行转换,那么运行时产生的错误将很难去定位和调试,然而有了泛型,编译器 可以帮助我们执行大量的类型检查,并且可以检测出更多的编译时错误。
泛型类和自定义泛型类
我们在java的集合类中应该会经常见到泛型类,List
public interface List<E> extends Collection<E>
如果考虑参数化一个类,请考虑是否满足以下条件:
一个核心类位于某种包装器的中心:也就是说,类中心的 “东西” 可广泛地应用,它周围的特性(例如属性)是相同的。
行为是相同的:无论类中心的 “东西” 是什么,都会执行完全相同的操作。
根据这两个条件,可以看到集合满足以下要求:
这个 “东西” 就是组成集合的类。
操作(比如 add、remove、size 和 clear)完全相同,无论集合由哪些对象组成。
我们可以自定义一个自己的泛型类(我写的例子不满足上述规范):
泛型方法和自定义泛型方法
如果我们在泛型类里面定义泛型方法,那么类型直接用就好,但是假如我们的类不是泛型类同时我们又想声明泛型方法,需要在方法体声明泛型;举例子说明:
public class MyClass {// Other possible stuff... ignore... public <E> String formatArray(E[] arrayToFormat) { StringBuilder sb = new StringBuilder(); int index = 0; for (E element : arrayToFormat) { sb.append("Element "); sb.append(index++); sb.append(" => "); sb.append(element); sb.append('\n'); } return sb.toString(); }// More possible stuff... ignore...}
无需参数化 MyClass,可以将您想要使用的一个方法泛型化,创建一个适合任何元素类型的一致的字符串表示。
**特别注意:我们的迭代器模式,只要实现Iteratable接口并返回Iterator就可以支持泛型,其中只要我们实现了这个接口,系统就会给我们foreach的语法糖。详细可以看:http://liuzxc.github.io/blog/java-advance-06/
http://blog.csdn.net/andie_guo/article/details/12871733(这一篇更好)**
- 深入java 认识泛型及其用法
- Java关键字及其用法
- JAVA枚举及其用法
- Java泛型简单认识
- JAVA多线程变量的深入认识(一)
- JAVA多线程变量的深入认识(二)
- JAVA多线程变量的深入认识(三)
- java jar文件的深入认识
- 深入认识Java中super关键字
- Java中jar文件的深入认识
- 深入认识javascript中eval函数的用法
- 深入认识javascript中eval函数的用法
- java泛型中的K,V,T,E,?,object的意思及其用法
- java泛型中的K,V,T,E,?,object的意思及其用法
- 深入java字符串原理及其效率分析
- java 泛型深入
- Java深入泛型
- Java ServerSocket用法深入分析
- Android 主题切换/换肤方案 研究(一)
- python基础教程——dict和se
- hive schematool 初始化 发生 'NUCLEUS_ASCII' Error
- linux 安装 node
- Andrew Ng笔记-week1
- 深入java 认识泛型及其用法
- <iframe>和<frame>区别
- 滴滴算法工程师面试2018
- 有序表查询之三:java实现斐波那契查询
- 连接池,为什么要使用连接池?
- 详解linux目录结构及重要子目录
- 简单的表格导出
- 链表
- 挖财—求数列的和