一、引子:

项目中使用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. RYU 的选择以及安装

    RYU 的选择以及安装 由于近期的项目需求,不得已得了解一下控制器内部发现拓扑原理,由于某某应用中的控制器介绍中使用的RYU,所以打算把RYU装一下试试.出乎意料的是,RYU竟是我之前装过最最轻便的控 ...

  2. 表格-table 样式

    .table: 表格基本样式 .table-dark:表格显示为黑色 .thead-light: 表头显示颜色跟亮 .thead-dark:表头显示为黑色 .table-striped:表格以条纹形式 ...

  3. 用javaScript将页面滚动条到底部

    ((JavascriptExecutor) driver).executeScript("document.body.scrollTop=500000"); 通过该方法可以将有滚动 ...

  4. Delphi 模式窗体返回值ModalResult的使用方法及注意事项(转)

    1.基础知识简介: ModalResult是指一个模式窗体(form.showmodal)的返回值,一般用于相应窗体上按钮的ModalResult属性: 显示完窗体(关闭)后,会返回此属性预设的值做为 ...

  5. 【设计模式】—— 职责链模式ChainOfResponsibility

    前言:[模式总览]——————————by xingoo 模式意图 避免请求的发送者,和接受者过度的耦合在一起.一个请求者只需要发送一个请求即可,它的请求具体由后面哪个对象进行响应,并不需要关心.而请 ...

  6. 前端开发【第5篇:JavaScript进阶】

    语句 复合表达式和空语句 复合表达式意思是把多条表达式连接在一起形成一个表达式 { let a = 100; let b = 200; let c = a + b; } 注意这里不能再块级后面加分号, ...

  7. Continuation-passing style

    Continuation-passing style 参考书籍: EOPL (  Essentials of Programming Languages, 3rd Edition ) 作者:知乎用户链 ...

  8. AtCoder Grand Contest 007

    AtCoder Grand Contest 007 A - Shik and Stone 翻译 见洛谷 题解 傻逼玩意 #include<cstdio> int n,m,tot;char ...

  9. 普通平衡树Treap(含旋转)学习笔记

    浅谈普通平衡树Treap 平衡树,Treap=Tree+heap这是一个很形象的东西 我们要维护一棵树,它满足堆的性质和二叉查找树的性质(BST),这样的二叉树我们叫做平衡树 并且平衡树它的结构是接近 ...

  10. 洛谷 P4112 [HEOI2015]最短不公共子串 解题报告

    P4112 [HEOI2015]最短不公共子串 题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的"子串"指的是它的连续的一段,例如bcd是 ...