头次写博客,想说的东西不难,关于泛型的疑问,是前一阵在学习jackson中遇到的。

下面就把我所想到的、遇到的,分享出来。

泛型是JDK1.5后的一个特性,是一个参数类型的应用,可以将这个参数声明在类、接口、方法中,就像我们方法中定义的局部变量一样;在工作中,我们常在List,Map,Set等集合对象中使用,或者我们自己声明的类中使用。

说到泛型,就不得说起“擦除”这个概念,相比于c#来说,java的泛型只存在于程序的源码中,在编译后的class文件中不存在,这个过程就是--泛型"擦除";所以,对于new ArrayList<String> 和 new ArrayList<Integer> 来说,两个对象在编译之后两者是一样的,通过反射均可以向集合中添加任意类型的对象;

 
 
 
 

可以看到,在编译后的class文件中,ArrayList所声明的泛型不存在了;由此可知,如果想在程序运行期间获取泛型,看似是一件不可能完成的事情!

直到学习了jackson后,我发现java泛型的“擦除”并不能一概而论;至少通过TypeReference接口,是可以获取到对象中的泛型;

 
 

一开始学习jackson,相关的api操作还不是很熟悉,json并没有转换成StudentEntity对象,而是变成了LinkedHashMap;研究后,发现可以使用TypeReference对象,来实现参数化类型的json转换;

 
 

有些疑问?按照之前所说,由于泛型“擦除”的原因,泛型在编译后的class文件中就不存在了,只会保留原始类型(Type中的概念),那么TypeReference又是如何实现,获取到了具体的泛型类型呢!

查看TypeReference的源码,发现在其构造方法中,主要使用到了getGenericSuperclass()和getActualTypeArguments
()两个方法,getGenericSuperclass()返回的是此对象带“泛型”的父类,而getActualTypeArguments()返回的是此父类中实际类型参数的Type 对象数组,说白了就是TypeReference<>中的泛型;

 
 

通过debug,发现确实获取到了new TypeReference<Map<String,StudentEntity>>中的泛型,至此我决定自己写个父类、子类,看看效果如何?

 
 

再次通过debug发现,并没有得到具体的泛型,而是获取到了ParameterizedTypeImpl对象(Type中的概念);此时,对于泛型更加疑惑了,感觉心中有千万只草泥马在奔腾!

于是,又回过头来看了下之前的代码 new TypeReference<Map<String,StudentEntity>>(){},发现此段代码其实是一个匿名的内部类,而编译器在编译的时候,会将此匿名内部类单独生成一个class文件,命名规则如下:主类+$+(1,2,3....)

 
 

通过反编译后,真相一目了然!

 
 

创建的匿名内部类new TypeReference<Map<String,StudentEntity>>(){},在生成的的class文件中,编译器默认为TypeReference中的泛型Map<String,StudentEntity>原始类型,并不会进行擦除!类似于 我们实际创建一个类 Class TypeReference<Map<String,StudentEntity>>{} 、 Class Test<T>{}一样,在编译后Map、T依旧会存在!

由此,对于java泛型的“擦除”并不能一概而论,在运行期间,如果方法中出现带泛型的匿名内部类,那么泛型依旧会被保留下来,我们可以通过对应的方法获取到实际的泛型类型!

上文中,提到的Type、原始类型的概念,在下一篇博客中提及!

作者:贾博岩
链接:https://www.jianshu.com/p/1f608fd05e20
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

关于Java泛型"擦除"的一点思考的更多相关文章

  1. Java泛型擦除

    Java泛型擦除: 什么是泛型擦除? 首先了解一下什么是泛型?我个人的理解:因为集合中能够存储随意类型的对象.可是集合中最先存储的对象类型一旦确定后,就不能在存储其它类型的对象了,否则,编译时不会报错 ...

  2. 关于Java泛型实现原理的思考与一般用法示例总结

    面向对象的一个重要目标是对代码重用的支持.支持这个目标的一个重要机制就是泛型机制.在1.5版本之前,java并没有直接支持泛型实现,泛型编程的实现时通过使用继承的一些基本概念来完成的. 这种方式的局限 ...

  3. JAVA泛型-擦除

    package com.xt.thinks15_7; import java.util.Arrays; class EraseObject1<A> { } class EraseObjec ...

  4. [转] Java 的泛型擦除和运行时泛型信息获取

    原文链接 https://my.oschina.net/lifany/blog/875769 前言 现在很多程序员都会在简历中写上精通 Java.但究竟怎样才算是精通 Java 呢?我觉得不仅要熟练掌 ...

  5. Java泛型的历史

    为什么Java泛型会有当前的缺陷? 之前的章节里已经说明了Java泛型擦除会导致的问题,C++和C#的泛型都是在运行时存在的,难道Java天然不支持“真正的泛型”吗? 事实上,在Java1.5在200 ...

  6. Java 泛型 Java使用泛型的意义

    Java 泛型 Java使用泛型的意义 @author ixenos 直接意义 在编译时保证类型安全 根本意义 a) 类型安全问题源自可复用性代码的设计,泛型保证了类型安全的复用模板 b) 使用复用性 ...

  7. java 泛型基础问题汇总

    泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Java语言引 ...

  8. Java泛型读书笔记 (二)

    关于Java泛型擦除后,继承一个泛型类带来的问题 有如下泛型类Pair: public class Pair<T> { private T second; private T first; ...

  9. 重学Java泛型

    一丶从字节码层面看范型擦除 public class Type1<T> { private T t; } 使用jclasslib插件查看其字节码: 可以看到 t属性的类型是List< ...

随机推荐

  1. Android性能优化之界面UI篇

    1.使用style.color.string.dimen样式来分离xml布局文件,减少代码的重复使用,增加代码复用率,防止hardcode,下面是一个例子: 在定义layout时候,因为每个View或 ...

  2. iOS监听模式系列之NSNotificationCenter的简单使用

    NSNotificationCenter 对于这个没必要多说,就是一个消息通知机制,类似广播.观察者只需要向消息中心注册感兴趣的东西,当有地方发出这个消息的时候,通知中心会发送给注册这个消息的对象.这 ...

  3. BMP 转 YUV (BMP2YUV)

    本文介绍BMP 转 YUV.其实这是以前"数据压缩"实验课上的内容,前几天有人问我相关的问题,突然发现自己有一段时间没有接触BMP也有些生疏了,因此翻出资料总结一下. BMP文件格 ...

  4. TCP连接建立系列 — TCP选项解析

    本文主要分析:在收到客户端的SYN包时,服务器端是如何解析它所携带的TCP选项,并结合本端情况决定是否予以支持. 内核版本:3.6 Author:zhangskd @ csdn blog 概述 收到客 ...

  5. objective-c中关于类型编码的解释

    在某些情况下,我们需要动态的向一个类插入一个实例方法(也可以是一个类方法):这时我们可以用class_addMethod函数来完成: BOOL class_addMethod ( Class cls, ...

  6. Twemproxy分析

    twemproxy(又称为nutcracker)是一个轻量级的Redis和Memcached代理,主要用来减少对后端缓存服务器的连接数. 由Twitter开源出来的缓存服务器集群管理工具,主要用来弥补 ...

  7. C# 视频多人脸识别

    上一篇内容的调整,并按 @轮回 的说法,提交到git了,https://github.com/catzhou2002/ArcFaceDemo 基本思路如下: 一.识别线程 1.获取当前图片 2.识别当 ...

  8. jsJqGrid

    /*展开收起*/ $(function() { initGridTable(); }); function change() { var flag = $("#searchTitle&quo ...

  9. 分享一个国内首个企业级开源的GO语言网关--GoKu API Gateway

    一. 简介 GoKu API Gateway,中文名:悟空API网关,是国内首个开源go语言API网关,帮助企业进行API服务治理与API性能安全维护,为企业数字化赋能. GoKu API Gatew ...

  10. 途牛java实习面试(失败)

    一进去让自己介绍.简单介绍了一下.然后让我自己说说框架.问题太大一紧张卡住了. 然后面试官开始问,让我介绍多线程,我就简单介绍了多线程.然后问我有没有做过多线程的项目,我说没有. 问了MySQL的锁和 ...