【Java范型七】范型消除
Java  /  管理员 发布于 4年前   305
范型是Java1.5引入的语言特性,它是编译时的一个语法现象,也就是说,对于一个类,不管是范型类还是非范型类,编译得到的字节码是一样的,差别仅在于通过范型这种语法来进行编译时的类型检查,在运行时是没有范型或者类型参数这个说法的。
范型跟反射刚好相反,反射是一种运行时行为,所以编译时不能访问的变量或者方法(比如private),在运行时通过反射是可以访问的,也就是说,可见性也是一种编译时的行为,在运行时,JVM中的字节码对彼此都是可见的。
Java在将源代码编译后,自动去除了关于范型的信息,范型是编译时的语法现象,这给范型的处理带来一些很不直观的结果。
package com.tom.lang.generics;public class Generics<T> { public static void main(String[] args) { Generics<String> stringGenerics =new Generics<String>(); if (stringGenerics instanceof Generics<String>) {//编译错, 范型类不能用于instanceof运算符 } }}
package com.tom.lang.generics;public class Generics<T> { public void method(Generics<String> obj) { //编译错,两个method冲突 } public void method(Generics<Integer> obj) { }}
Data<Integer>.class //范型类加.class来获得它的class对象
Gson这个GSON算是比较优雅的解决了范型的问题,但是范型的运行时消除这个特性还是给使用Gson带来一些额外的代码,比如如下的代码不用任何额外处理时
package com.tom.lang.generics;import com.google.gson.Gson;class Point { private int x; private int y; public Point(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; }}class Data<T> { private T data; public Data(T data) { this.data = data; } public T getData() { return data; }}public class DataTest { public static void main(String[] args) { Data<Point> d = new Data<Point>(new Point(100,200)); String str = new Gson().toJson(d); System.out.println(str); Data<Point> dd = new Gson().fromJson(str, Data.class); //虽然dd看上去像是一个带有参数类型为Point的Data范型类变量,实际上运行时得到的结果是,Data含有一个data字段,但是这个字段 //是TreeMap类型的,由于运行的范型消除,所以,即使返回的dd中的data字段是Map类型,仍然不会报错! //Point p = dd.getData(); //运行时,类型转换失败 Map map = dd.getData(); //成功 }}
上面的正确做法
package com.tom.lang.generics;import com.google.gson.Gson;import com.google.gson.reflect.TypeToken;import java.lang.reflect.Type;class Point { private int x; private int y; public Point(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; }}class Data<T> { private T data; public Data(T data) { this.data = data; } public T getData() { return data; }}public class DataTest { public static void main(String[] args) { Data<Point> d = new Data<Point>(new Point(100,200)); String str = new Gson().toJson(d); System.out.println(str); Type type = new TypeToken<Data<Point>>(){}.getType();//将范型类型包装到TypeToken中保存 Data<Point> dd = new Gson().fromJson(str, type); //转型正确 Point p = dd.getData();//可以正确取值 }}
123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..路人 在
php中使用hyperf框架调用讯飞星火大模型实现国内版chatgpt功能示例中评论 教程很详细,如果加个前端chatgpt对话页面就完美了..Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号