一、引子:

项目中使用Gson的反序列化将json转化成具体的对象,具体方法是:

package com.google.gson;下的反序列化方法

 public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException{
......
}

参数<T> :the type of the desired object

参数json:要被反序列化的json数据;

参数typeOfT:指定的通用类型的src。可以通过 Type typeOfT = new TypeToken&lt;Collection&lt;Foo&gt;&gt;(){}.getType();获得;

边对象:使用了泛型类

 public class CtiEdgeT<T,V> {
private String id;
//顶点
private T inVertex;
//对应点
private V outVertex;
......
}

最开始考虑使用具体的model作为参数,例如CtiEdgeT<DomainVertex,IpVertex> 具体类型(DomainVertex,IpVertex)做为参数,通过gson反序列化获得具体类型的CtiEdgeT<SampleVertex,IpVertex>对象,例如:

  private boolean saveEdgeToGraph(String msg, String inType, String outType) {
boolean flag = false;
switch (inType){
case Constant.SAMPLE_LABEL:{
switch (outType){
case Constant.IP_LABEL:{
Type type = new TypeToken<CtiEdgeT<SampleVertex,IpVertex>>() {
}.getType();
CtiEdgeT<SampleVertex,IpVertex> edge = JsonUtil.getJson().fromJson(msg, type);
flag = this.doSaveEdgeToGraph(inType,outType,edge.getInVertex(),edge.getOutVertex(),edge);
break;
}
case Constant.DOMAIN_LABEL:{
Type type = new TypeToken<CtiEdgeT<SampleVertex,DomainVertex>>() {
}.getType();
CtiEdgeT<SampleVertex,DomainVertex> edge = JsonUtil.getJson().fromJson(msg, type);
flag = this.doSaveEdgeToGraph(inType,outType,edge.getInVertex(),edge.getOutVertex(),edge);
break;
}
。。。。。。
}
}
}
}

本项目中就有20+种数据,即20+个model,这样做导致的结果就是如果有很多不同的边CtiEdgeT<T,V>,将会写大量的冗余代码。

二、解决方案:

可以通过 ParameterizedType 这个接口实现泛型类,参数化类型,参考这篇文章: https://www.jianshu.com/p/b1ad2f1d3e3e

具体实现如下:

EdgeParameterTypeImpl:
 import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; public class EdgeParameterTypeImpl implements ParameterizedType { //边
private Class ctiEdgeT ;
//顶点
private Class inVertex ;
//对应点
private Class outVertex ; public EdgeParameterTypeImpl(Class ctiEdgeT,Class inVertex,Class outVertex) {
this.ctiEdgeT = ctiEdgeT ;
this.inVertex = inVertex ;
this.outVertex = outVertex ;
} @Override
public Type[] getActualTypeArguments() {
return new Type[]{inVertex,outVertex};
} @Override
public Type getRawType() {
return ctiEdgeT;
} @Override
public Type getOwnerType() {
return null;
} }
 边 CtiEdgeT<T,V>:
 public class CtiEdgeT<T,V> {
private String id;
//顶点
private T inVertex;
//对应点
private V outVertex; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public T getInVertex() {
return inVertex;
} public void setInVertex(T inVertex) {
this.inVertex = inVertex;
} public V getOutVertex() {
return outVertex;
} public void setOutVertex(V outVertex) {
this.outVertex = outVertex;
}
}

通过参数化泛型解决,传入的具体model类作为参数,反序列化得到具体的边

 private boolean saveEdgeToGraph(String msg, String inType, String outType) {
boolean flag = false;
Class<?> inVertex = Constant.vertexClassMap.get(inType); //inType : SAMPLE_LABEL
Class<?> outVertex = Constant.vertexClassMap.get(outType); //outType : IP_LABEL
EdgeParameterTypeImpl type = new EdgeParameterTypeImpl(CtiEdgeT.class, inVertex, outVertex);
@SuppressWarnings("rawtypes")
CtiEdgeT edge = JsonUtil.getJson().fromJson(msg,type);
flag = this.doSaveEdgeToGraph(inType,outType,edge.getInVertex(),edge.getOutVertex(),edge);
return flag;
}
从vertexClassMap中取对应的具体model
 public class Constant {
@SuppressWarnings("rawtypes")
public static Map<String,Class> vertexClassMap = new HashMap<String,Class>(); static{
try {
vertexClassMap.put(SAMPLE_LABEL,SampleVertex.class);
vertexClassMap.put(IP_LABEL,IpVertex.class);
vertexClassMap.put(DOMAIN_LABEL,DomainVertex.class);
。。。。。。
}
}
}

通过追踪代码:CtiEdgeT edge = JsonUtil.getJson().fromJson(msg,type);可以发现type的源码

   TypeToken(Type type) {
this.type = $Gson$Types.canonicalize($Gson$Preconditions.checkNotNull(type));
this.rawType = (Class<? super T>) $Gson$Types.getRawType(this.type);
this.hashCode = this.type.hashCode();
}
   public static Type canonicalize(Type type) {
if (type instanceof Class) {
Class<?> c = (Class<?>) type;
return c.isArray() ? new GenericArrayTypeImpl(canonicalize(c.getComponentType())) : c; } else if (type instanceof ParameterizedType) {
ParameterizedType p = (ParameterizedType) type;
return new ParameterizedTypeImpl(p.getOwnerType(),
p.getRawType(), p.getActualTypeArguments()); }
......
}

上面标红的代码会执行具体model的实现类的方法,得到具体的类型。

三、拓展点:

关于ParameterizedType 的解析可以 参考这篇文章: https://blog.csdn.net/a327369238/article/details/52622331

 public class ParameterTest {
public static void main(String[] args) {
Method method = null;
try {
//这里的第二个参数,和getRawType()意义类似
method = new ParameterTest().getClass().getMethod("test", HashMap.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
Type[] types = method.getGenericParameterTypes();
ParameterizedType ptype = (ParameterizedType) types[0];
Type rawType = ptype.getRawType();
System.out.println("最外层<>前面那个类型 rawType:"+rawType);
Type type = ptype.getActualTypeArguments()[0];
Type type1 = ptype.getActualTypeArguments()[1];
System.out.println("泛型 type:"+type);
System.out.println("泛型 type1:"+type1);
Type ownerType = ptype.getOwnerType();
System.out.println("ownerType:"+ownerType);
//type是Type类型,但直接输出的不是具体Type的五种子类型,
//而是这五种子类型以及WildcardType具体表现形式
System.out.println("泛型 type name:"+type.getClass().getName());
}
public void test(HashMap<String,Integer> a){
}
}

结果:

 最外层<>前面那个类型 rawType:class java.util.HashMap
泛型 type:class java.lang.String
泛型 type1:class java.lang.Integer
ownerType:null
泛型 type name:java.lang.Class

因此 EdgeParameterTypeImpl 中的

public Type getRawType() {   return ctiEdgeT;} 得到 边ctiEdgeT,而边 CtiEdgeT<T,V> 是参数是泛型,

public Type[] getActualTypeArguments() { return new Type[]{inVertex,outVertex};} 得到 参数 inVertex,outVertex

----------------------------------------------多做多解决多总结-----------------------------------

Java反射--基于ParameterizedType实现泛型类,参数化类型的更多相关文章

  1. Java 反射 ParameterizedType 参数化类型

    /***************************************************************************************** * Java 反射 ...

  2. 基于NACOS和JAVA反射机制动态更新JAVA静态常量非@Value注解

    1.前言 项目中都会使用常量类文件, 这些值如果需要变动需要重新提交代码,或者基于@Value注解实现动态刷新, 如果常量太多也是很麻烦; 那么 能不能有更加简便的实现方式呢? 本文讲述的方式是, 一 ...

  3. 基于Java反射的map自动装配JavaBean工具类设计

    我们平时在用Myabtis时不是常常需要用map来传递参数,大体是如下的步骤: public List<Role> findRoles(Map<String,Object> p ...

  4. Java反射机制的学习

    Java反射机制是Java语言被视为准动态语言的关键性质.Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调 ...

  5. Java反射机制(转载)

    原文链接:http://www.blogjava.net/zh-weir/archive/2011/03/26/347063.html Java反射机制是Java语言被视为准动态语言的关键性质.Jav ...

  6. 详解Java反射各种应用

    Java除了给我们提供在编译期得到类的各种信息之外,还通过反射让我们可以在运行期间得到类的各种信息.通过反射获取类的信息,得到类的信息之后,就可以获取以下相关内容: Class对象 构造器 变量 方法 ...

  7. (转载)Java反射机制

    Java反射机制是Java语言被视为准动态语言的关键性质.Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调 ...

  8. java反射基础知识(五)反射应用实践

    详解Java反射各种应用   Java除了给我们提供在编译期得到类的各种信息之外,还通过反射让我们可以在运行期间得到类的各种信息.通过反射获取类的信息,得到类的信息之后,就可以获取以下相关内容: Cl ...

  9. 深入分析Java反射(三)-泛型

    前提 Java反射的API在JavaSE1.7的时候已经基本完善,但是本文编写的时候使用的是Oracle JDK11,因为JDK11对于sun包下的源码也上传了,可以直接通过IDE查看对应的源码和进行 ...

随机推荐

  1. 第二阶段团队冲刺——One

    个人任务: 司宇航:处理第一次启动服务器500的问题. 季方:优化cookie第一次运行出错的问题. 王金萱:修改注册界面. 马佳慧:修改登录界面. 站立会议: 任务看板和燃尽图:

  2. 数学口袋精灵app(小学生四则运算app)开发需求

    数学口袋精灵APP,摒除了传统乏味无趣学习数学四则运算的模式,采用游戏的形式,让小朋友在游戏中学习,培养了小朋友对数学的兴趣,让小朋友在游戏中运算能力得到充分提升.快乐学习,成长没烦恼! 项目名字:“ ...

  3. NetFPGA Demo ——reference_nic_nf1_cml

    NetFPGA Demo --reference_nic_nf1_cml 实验平台 OS:deepin 15.4 开发板:NetFPGA_1G_CML 实验过程 从NetFPGA-1G-CML从零开始 ...

  4. 基于OVS的VLAN虚拟化简易实践方案

    基于OVS的VLAN虚拟化简易实践方案 前言 本实验基于ovs的vlan流表匹配,根据端口进行vlan标签插入.手工配置ovs,使其具有vlan虚拟化方案. 实验拓扑 ---- ---- | h1 | ...

  5. Access restriction: The type 'BASE64Decoder' is not API

    Access restriction: The type 'BASE64Decoder' is not API (restriction on required library 'C:\Program ...

  6. echarts实现环形图

    前端框架使用的angular,使用echarts实现环形图 1. item.component.html <div id="box1" class="pie&quo ...

  7. IDEA中新建Module时Module name、Content root、Module file location的含义

    如下图测试: 最开始默认情况下,Content root.Module file location两行,最末尾的数据跟Module name是相同的. 现在对三行数据,强制进行不同的命名,Finish ...

  8. 【刷题】BZOJ 2194 快速傅立叶之二

    Description 请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5. a,b中的元素均为小于等于100的非 ...

  9. Problem A: 道路建设 解题报告

    一定存在一个最优解是一条链 否则可以接上去,不会更差 边权最小的边一定在这条链上 这个比较显然 可以把所有边都减去这个最后加上就行了 把链上的边按距离当前根的深度从小到大排列,设第一个零边位置为\(k ...

  10. springmvc接收数组类型参数

    直接在方法上使用List<Bean>报不能实例化错误! 必须将List<Bean>放在某个对象里作为属性方可接收.具体见如下例子 前端代码 <!DOCTYPE html& ...