当前位置: 首页 > wzjs >正文

辽宁建设局网站首页下载百度网盘app

辽宁建设局网站首页,下载百度网盘app,科技魏,苏州建设公司有哪些一.泛型擦除 泛型擦除是什么&#xff1f; 众所周知&#xff0c;Java的泛型只在编译时有效&#xff0c;到了运行时这个泛型类型就会被擦除掉&#xff0c;即List<String>和List<Integer>在运行时其实都是List<Object>类型。 为什么选择这种实现机制&#xf…

一.泛型擦除

泛型擦除是什么?

众所周知,Java的泛型只在编译时有效,到了运行时这个泛型类型就会被擦除掉,即List<String>List<Integer>在运行时其实都是List<Object>类型。

为什么选择这种实现机制?不擦除不行么? 在Java诞生10年后,才想实现类似于C++模板的概念,即泛型。Java的类库是Java生态中非常宝贵的财富,必须保证向后兼容(即现有的代码和类文件依旧合法)和迁移兼容(泛化的代码和非泛化的代码可互相调用)基于上面这两个背景和考虑,Java设计者采取了"类型擦除"这种折中的实现方式。

同时正正有这个这么"坑"的机制,令到我们无法在运行期间随心所欲的获取到泛型参数的具体类型。

泛型在什么时候擦除?是怎么擦除的?

编译的时候会进行泛型擦除,如果不加限制的话被擦除后在JVM里面变成Object,如果使用extends规定了泛型上界的话,就是以这个上界的类型存储在JVM中。

/**
*编译前的类
*/
public class MainTest2<T extends Number> {private T field;public T function(T value) {return value;}}/**
*编译后字节码后,反编译出的结果
*/
public class MainTest2 {private Number field;public Number function(Number value) {return value;}
}

什么情况下不进行泛型擦除?

父类泛型、成员变量、方法入参和返回值使用到的泛型信息都会保留,并能在运行阶段获取。

//里面所有的泛型都不会被擦除
public class Clazz extends ArrayList<String> {public Map<String, Integer> field;public Set<String> function(List<Number> list) {return null;}}

众所周知,java是在Java5的时候引入的泛型,为了支持泛型,JVM的class文件也做了相应的修改,其中最重要的就是新增了Signature属性表,java编译为字节码后,其申明的泛型信息都存储在Signature中,通过反射获取的泛型信息都来源于这里。

而Signature属性表可以被class文件,字段表,方法表携带,这就使得:类声明,字段声明,方法声明中的泛型信息得以保留。

泛型擦除的仅仅是Code属性表里面的内容,而方法体在字节码中正是存放在Code属性表的。

所谓的java泛型擦除可以理解为只是擦除了方法体的泛型信息。

二.Gson的的TypeToken原理

我们都知道Gson序列化和反序列化是怎么实现的,比如说服务器返回的json数据格式是下面这样的:

{"code":200,"message":"success","data":"{...}"
}

其中data对应的结构不定, 一种考虑是使用泛型:

public class Response<T>{public T data;//简化数据, 省略了其他字段
}

我们把服务器返回的数据转化为Response,反序列化会通过以下代码实现:

String json = "{\"data\":\"data from server\"}";
Type type = new TypeToken<Response<String>>(){}.getType();
Response<String> result = new Gson().fromJson(json, type);

我们为什么需要使用TypeToken来反序列化呢?

这是因为如果我们直接传递Response<String>过去,因为存在泛型擦除,编译过后在JVM里面拿到的是Response<Object>。

这个TypeToken是什么东西呢?

  protected TypeToken() {this.type = getSuperclassTypeParameter(getClass());this.rawType = (Class<? super T>) $Gson$Types.getRawType(type);this.hashCode = type.hashCode();}static Type getSuperclassTypeParameter(Class<?> subclass) {Type superclass = subclass.getGenericSuperclass();if (superclass instanceof Class) {throw new RuntimeException("Missing type parameter.");}ParameterizedType parameterized = (ParameterizedType) superclass;return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);}

可以看到TypeToken的构造函数加了protected修饰,为什么需要加protected呢?

当将构造函数标记为protected,意味着该构造函数只能被同包内或者子类访问到。TypeToken所在的包名是package com.google.gson.reflect,肯定和我们项目不是一个包名。所以这里使用protected的真正意图是让我们创建TypeToken的子类。

我们知道存在Signature属性表里面的泛型不会被擦除调用,Signature属性表又被Class文件携带。

如果我们直接new TypeToken<Response<String>>().getType()的话,还是会被泛型擦除啊!如果是定义一个内部类,内部类上的泛型是不会被擦除的,我们就能正常反序列化了。

 

http://www.dtcms.com/wzjs/259124.html

相关文章:

  • 微官网站怎么做搜狗搜索推广
  • 做360手机网站快速微信营销典型案例
  • 网站做导航的地图seo网站优化助理
  • wordpress插件目录下锦绣大地seo官网
  • 淘宝网站开发方式电话营销外包公司
  • 常州手机网站效果运营推广的方式和渠道
  • 做推广网站多少钱seo必备工具
  • wordpress smtp qqseo网络推广是干嘛的
  • 做h5的网站有哪些如何在百度提交自己的网站
  • 洛阳网站建设网站建设百度搜索风云榜单
  • 北京单页营销型网站制作十大最免费软件排行榜
  • 做ppt图片用的网站有哪些问题新乡百度关键词优化外包
  • 网站做赌博词怎么推广连云港seo优化
  • 做外链的博客网站营销团队
  • wordpress 新窗口站长工具seo综合查询收费吗
  • 扬中网站建设公司全网推广
  • 昆明网站的建设免费crm客户管理系统
  • 一个网站如何做cdn加速郑州网站优化公司
  • 网站中的下拉菜单日喀则网站seo
  • 备案用的网站建设方案书怎么写营销策划方案ppt
  • 云南住房和建设厅网站首页信息流优化
  • 代备案网站网站到首页排名
  • 免费网站制作app编程培训
  • 自己建网站教程html底部友情链接代码
  • 电商网站开发团队怎么创建个人网站
  • 做一公司网站优化快速排序
  • 小型网站开发时间周期如何购买域名
  • 高端定制网站设计公司二级域名网站查询入口
  • 深圳罗湖外贸网站建设友情链接实例
  • 怎么进入网站管理页面百度手机助手下载安装最新版