作者:面试君
引言
在讲阿里fastjson 之前,先讲下泛型的一些基础知识和在反射中如何获取泛型,觉得自己已经掌握的可以直接通过目录跳到最后查看
泛型类
泛型类的定义只要在申明类的时候,在类名后面直接加上< E>,中的E可以是任意的字母,也可以多个,多个用逗号隔开就可以。示例代码如下
public class SelfList {}
泛型类中的实际类型的推断
那么什么时候确定这个E 的具体类型呢?其实是在new 一个对象的时候指定的,请看下面代码
![d6b90de9b8c82efe8adb63c650b79104.png](https://i-blog.csdnimg.cn/blog_migrate/5abe9bdb97580096d251dd3577218367.jpeg)
泛型接口
泛型接口和类的使用方式一样
![31e198721918e889b8143d9a34955126.png](https://i-blog.csdnimg.cn/blog_migrate/bb4c275e320c4992ecb6a4d3bb8c6db6.jpeg)
泛型方法
这个我觉得是相对来说比较难得,大家集中注意力听我说,说不定你以前一直以为的泛型方法是假的。好,先给个假的泛型方法给大家验一下,还是上面代码的例子,为了方便阅读我再贴一遍代码
![ff55e1ef6f435ff744f77cdb6b5813e8.png](https://i-blog.csdnimg.cn/blog_migrate/476c2c1b6957d0c6dfd9657871c08ede.jpeg)
泛型方法的定义
好了,重点来了,给个真正的泛型方法定义出来
![f8fa2041295ad70f61553b6eb9b99149.png](https://i-blog.csdnimg.cn/blog_migrate/71a6918b82cae1894e5e5e5dc4a53fd7.jpeg)
![0380fdda1c6a22860cbe1d0b1fdecd2c.png](https://i-blog.csdnimg.cn/blog_migrate/74ed243afec73b200fdcf4010a71d06c.jpeg)
输出结果
I am Integer
当参数列表中有多个参数使用了相同的泛型变量,返回值类型也使用了该变量,那么返回值类型由他们的公共父类来决定最终的泛型类型![60eeb7781db8c87c496efc8eea85d35e.png](https://i-blog.csdnimg.cn/blog_migrate/03b32c82edb0e5fd131cfa79687312a8.jpeg)
注意上面的输出还会是
I am Integer
因为根据第一条规则,传进去的是什么类型就是什么类型,但是返回值类型候需要根据第二条规则来确定
反射中的泛型使用
上面说的都是在编译之前就可以确定的泛型。大家知道,泛型运行的时候其实是会被擦除的。不过没关系,还是提供给我们通过反射的方式来获取。首先我来认识下java中的泛型类型继承结构
![8df928e375ceffa425077e41813fade8.png](https://i-blog.csdnimg.cn/blog_migrate/9ab8aeae5a5b6b8ce3a3753bf4bc245f.jpeg)
这里主要讲平时运用最多的三个类,其他还有一些GenericArrayType 之类的就不讲了,大家按着我这个分析的思路去看下就可以
ParameterizedType 源码
![afde42d8853c6b18ceaceb0218434e9d.png](https://i-blog.csdnimg.cn/blog_migrate/019fda1f73c950a5aff778d42b714cd1.jpeg)
ParameterizedType 测试验证
定义一个有内部类的类
![4c19376981a4d92f29a8d6e0ea36e4ca.png](https://i-blog.csdnimg.cn/blog_migrate/5da83e02f0e0b0e82f0a51261243d3df.jpeg)
写一个测试类
![dc98cbc51ec726b24bbec85b93122bc0.png](https://i-blog.csdnimg.cn/blog_migrate/1e210d9c549bb960d1031d6de97bbcff.jpeg)
输出结果
![1d73976008fb10d9b78487a9c1f7eaed.png](https://i-blog.csdnimg.cn/blog_migrate/29c626d3da0b31fad8fca459835c8192.jpeg)
TypeVariable 源码
![fca30d01be50011dbbe1ad597dfe1c40.png](https://i-blog.csdnimg.cn/blog_migrate/7ee6b6caecdf648eb55be4c318d6c29a.jpeg)
写一个测试类
![f3591786a9515b2d5edd60137340d2cf.png](https://i-blog.csdnimg.cn/blog_migrate/b1aafc92f734edcd547bf5bc0497f72e.jpeg)
输出的结果
![8cbdfc8f81c82503e4cbc2bfc70fb018.png](https://i-blog.csdnimg.cn/blog_migrate/65b5ef5bdb741c2f121a2617a1b47550.jpeg)
阿里fastjson 泛型的巧妙运用
看到下面这段代码,简单的意思就是从redis 获取字符串,然后转换为指定的泛型的类。大家可以留意到这里创建了个TypeReference 匿名类 注意后面是有带{}的,所以是实例化一个匿名内部类(这是重点中的重点,一切的魔术从这里开始),而不是TypeReference 这个类的实例
![ebc2027c3b24d86714e00a8101b25422.png](https://i-blog.csdnimg.cn/blog_migrate/25ae055c1a3b38eb5778d507658954d5.jpeg)
窥探源码
点进去看看这个源码
![d5bbc7e70aedba0a6c37c01f840907a4.png](https://i-blog.csdnimg.cn/blog_migrate/cf618a9b4edcd8157fd6b6842fd06e77.jpeg)
最后,我自己是一名从事了多年开发的JAVA老程序员,辞职目前在做自己的java私人定制课程,今年年初我花了一个月整理了一份最适合2019年学习的java学习干货,可以送给每一位喜欢java的小伙伴,想要获取的可以关注我的头条号并在后台私信我:交流,即可免费获取。
![d211eeb6e56a60152eebfdbfa208ba35.png](https://i-blog.csdnimg.cn/blog_migrate/e558310af888abbf957ca98d995bfed4.jpeg)