一、引子:

项目中使用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. linux内核分析--计算机是如何工作的

    实验部分 使用gcc -S -o main.s main.c -m32命令将源代码编译成汇编代码. 源代码如下: int g(int x) { return x + 9; } int f(int x) ...

  2. javascript 数组对象及其方法

    数组声明:通过let arr = new Array(); 或者 let arr = []; 数组对象可调用的方法: 1)find方法,使用情况是对数组进行筛选遍历,find方法要求某个函数(A)作为 ...

  3. c++实现计算器功能 -----初代

    由于时间问题,我就写的简单一点. 课程作业一 git链接: Operations 里面的Operations.cpp文件就是完成品. 1 我就简单的对我原来的代码进行了重构,原本的代码已经把函数都分得 ...

  4. 作业一_随笔1_初来乍到:学号&博客地址

    031302540——http://www.cnblogs.com/yyj031302540/ 计算机实验班叶艺洁

  5. 第二个Sprint冲刺第六天(燃尽图)补

  6. Spring之redisyi一主一从复制(非哨兵模式)

    看了好几天redis了,公司从刚开始的redisluster变成了redis主从,原因是rediscluster不可控,其实是我水平没到,万一出点啥事,我这个负责人都解决不了,那就完了!大数据平台下, ...

  7. 组件 -- Button

    .btn --------------------------------- button的背景色: .btn-primary .btn-success .btn-secondary .btn-dan ...

  8. Angular中通过$location获取地址栏的参数详解

    Angular中通过$location获取url中的参数 最近,项目开发正在进行时,心有点燥,许多东西没来得及去研究,今天正想问题呢,同事问到如何获取url中的参数,我一时半会还真没想起来,刚刚特意研 ...

  9. 2017年11月GitHub上最热门的Java项目出炉

    2017年11月GitHub上最热门的Java项目出炉~ 一起来看看这些项目你使用过哪些呢? 1分布式 RPC 服务框架 dubbohttps://github.com/alibaba/dubbo S ...

  10. CF1110C Meaningless Operations(构造题)

    这可能是我打那么多次CF比赛时,做出来的最难的一道题了……而且这题也是个绝世好题…… 题目链接:CF原网  洛谷 题目大意:$q$ 组询问,每次给定 $a$ 询问 $\gcd(a\&b,a\o ...