Java泛型学习
一、概念
在 Java 语言处于还没有出现泛型的版本时,只能通过 Object 是所有类型的父类和类型强制转换两个特点的配合来实现类型泛化。这样做有个缺点,就是只有程序员和运行期的虚拟机才知道这个 Object 到底是个什么类型的对象。在编译期,编译器无法检查这个 Object 的强制转换是否成功。因此,许多 ClassCastException 的风险就会转移到程序运行期之中。
泛型是 JDK 1.5 的一项新增特性,它的本质是参数化类型(Parametersized Type),就比如我们定义方法的时候,定义一个变量,称为形参,变量值根据传进去的实参的值不同而改变。而泛型的出现,就是为了解决类型也能根据传进去的类型改变的问题,也就是说所操作的数据类型被指定为一个参数。主要用在定义类、接口、方法的创建上,可以很好的减少代码的重复。
然而美中不足的是,Java 中的泛型实现并不是真正的泛型,它只在程序源码中存在,在编译后的字节码文件中,就已经替换为原来的原生类型了,并在相应的地方插入了强制转换代码,因此对于运行期的 Java 语言来说,ArrayList<int> 与 ArrayList<String> 就是同一个类,这种实现方法被称为泛型的类型擦除,所以泛型技术实际上是 Java 语言的一颗语法糖。
tips:语法糖虽然不会提供实际性的功能改进,但是他们或能提高工作效率,或能提升语法的严谨性,或能减少编码出错的机会。常见的语法糖还有“内部类”、“自动装箱/拆箱”、“断言语句”、“枚举类”等等
二、泛型使用
1. 泛型中的标识符含义
2、定义一个泛型方法
首先,泛型的声明,必须在方法的修饰符(public, static, final, abstract 等)之后,返回值声明之前,可以声明多个泛型,用逗号隔开。
public static <T1, T2> T1 print(List<T1> list, List<T2> list2) {
return list.get(0);
}
3、定义一个泛型类
@Data
public class Box<T> {//这里可以定义多个泛型,用逗号分割 private String name;
private T t; /**
* 泛型继承
*/
public static class CircleBox extends Box<String> { } public static class SquareBox extends Box<Integer> { }
}
三、泛型擦除
接下来我们来看一个泛型擦除的例子
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("hello", "hello");
map.put("world", "world");
System.out.println(map.get("hello"));
System.out.println(map.get("world"));
}
把这段 Java 代码编译成 Class 文件,然后再用字节码反编译工具进行反编译后,会发现所有泛型都不见了,泛型类型都变回了原生类型,只是在相应的地方做了类型强制转换。
public static void main(String[] args) {
HashMap map = new HashMap();
map.put("hello", "hello");
map.put("world", "world");
System.out.println((String)map.get("hello"));
System.out.println((String)map.get("world"));
}
四、泛型识别
按照我们上面的说法,泛型在编译期间就被擦除了,那么在代码运行期各种场景(如反射等)下该如何识别参数化类型呢?总不能识别出来都是 Object 吧?这就要说到一个虚拟机属性 —— Signature,它的作用就是存储一个方法在字节码层面的特征签名,这个属性保存的参数类型并不是原生类型,而是包括了参数化类型的信息。
因此,擦除法所谓的擦除,仅仅是对方法的 Code 属性中的字节码进行擦除,实际上元数据中还是保留了泛型信息,这也是我们能通过反射等手段取得参数化类型的根本依据。
Java泛型学习的更多相关文章
- Java泛型学习笔记 - (七)浅析泛型中通配符的使用
一.基本概念:在学习Java泛型的过程中, 通配符是较难理解的一部分. 主要有以下三类:1. 无边界的通配符(Unbounded Wildcards), 就是<?>, 比如List< ...
- Java泛型学习笔记--Java泛型和C#泛型比较学习(一)
总结Java的泛型前,先简单的介绍下C#的泛型,通过对比,比较学习Java泛型的目的和设计意图.C#泛型是C#语言2.0和通用语言运行时(CLR)同时支持的一个特性(这一点是导致C#泛型和Java泛型 ...
- java泛型学习(2)
一:深入泛型使用.主要是父类和子类存在泛型的demo /** * 父类为泛型类 * @author 尚晓飞 * @date 2014-7-15 下午7:31:25 * * * 父类和子类的泛型. * ...
- Java泛型学习---第二篇
泛型学习第一篇 1.泛型之擦拭法 泛型是一种类似"模板代码"的技术,不同语言的泛型实现方式不一定相同. Java语言的泛型实现方式是擦拭法(Type Erasure). 所谓擦拭法 ...
- java泛型学习(1)
java泛型(Generices Type) --->概念:泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和 ...
- Java泛型学习一
Java泛型 所谓泛型,就是变量类型的参数化.泛型是java1.5中引入的一个重要特征,通过引入泛型,可以使编译时类型安全,运行时更少抛出ClassCastException的可能.一提到参数化,最熟 ...
- Java 泛型学习总结
前言 Java 5 添加了泛型,提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型. 泛型的本质是参数化类型,可以为以前处理通用对象的类和方法,指定具体的对象类型.听起来有点抽象, ...
- java 泛型学习随笔
对于java 泛型 编译时处理,运行时擦除的特点理解 对于编译时处理 在使用泛型相关的类或方法时,如果声明时的类型和具体使用时的类型不一致则直接会编译不通过 对于运行时擦除 当在运行时对两个相同类型但 ...
- Java泛型学习笔记 - (六)泛型的继承
在学习继承的时候, 我们已经知道可以将一个子类的对象赋值给其父类的对象, 也就是父类引用指向子类对象, 如: Object obj = new Integer(10); 这其实就是面向对象编程中的is ...
- java 泛型学习
http://blog.csdn.net/archie2010/article/details/6232228 学习集合框架的时候经常用hasmap<Integer,Integer>就是泛 ...
随机推荐
- .exe简单的更新软件demo
百度网盘源码加文件:http://pan.baidu.com/s/1qYe2Vgg 功能:通过网站更新用户的软件,需要联网,也可以通过本地网站更新局域网用户软件. 根本实现:1.一个网站(本地就可以) ...
- 第一章:Druid简介
第一章:Druid简介 声明 公司的项目中用到了Druid(不是阿里的连接池),由于网上没有中文的文档,所以只好阅读官方文档.本人第一次阅读英文的文档,非常吃力,借助翻译工具和自己的理解阅读了Duri ...
- Maven的下载,安装,配置,测试,初识
1:Maven官网:http://maven.apache.org/ Maven远程仓库:http://search.maven.org/ 2:Maven是一个采用纯Java编写的开源项目管理工具,M ...
- 开发Angular库的简单指导(译)
1. 最近工作上用到Angular,需要查阅一些英文资料,虽然英文非常烂,但是种种原因又不得不硬着头皮上,只是每次看英文都很费力,因此决定将一些比较重要的特别是需要反复阅读的资料翻译一下,以节约再次阅 ...
- Excel 中使用sql语句查询
将Excel连接Oracle数据库 Excel选项板中"数据"—"自其他来源"下拉菜单中有有个可以连接其它数据库的选项"来自数据连接向导"和 ...
- websoket使用Protocol Buffers3.0传输
Protocol Buffers是Google推出的一个数据交换格式,相对于xml它的体积更小,更快,因为它是二进制传输的.3.0相对于2.0变动比较大.这些变动可以去看官方说明. 在前端使用Prot ...
- 基于AngularJS的过滤与排序【转载】
程序设计分析 首先,如果要是先查询过滤,就要使用到AngularJS中的 过滤器filter 了. 直接在表达式的后面使用管道命令符 | ,按照下面的写法就可以达到一个过滤的效果: {{ person ...
- APP品牌具体有哪几个要素?又是如何操作的?
对于品牌的一些认识 首先我们要知道,品牌是由用户与公司及其产品&服务互动后所产生的,失去了与用户互动并且承认的是伪品牌,对于开发者来说,APP的品牌要先从标志与颜色考虑起,但实话实说,标志与颜 ...
- 使用Apache Spark 对 mysql 调优 查询速度提升10倍以上
在这篇文章中我们将讨论如何利用 Apache Spark 来提升 MySQL 的查询性能. 介绍 在我的前一篇文章Apache Spark with MySQL 中介绍了如何利用 Apache Spa ...
- 如何解决 chrome 58 版本更新导致的 fiddler https 抓包不可用问题
注意!如果该方法不生效,请先卸载原有 fiddler 后再进行新版本 fiddler 安装步骤即可. chrome 于(上周?上上周?)推送了chrome 58 版本的更新,这次更新中直接去掉了证书未 ...