博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java 获取泛型的类型
阅读量:6513 次
发布时间:2019-06-24

本文共 4467 字,大约阅读时间需要 14 分钟。

hot3.png

Java 泛型实际上有很多缺陷,比如不能直接获取泛型的类型,不能获取带泛型类等。

以下方式是不正确的:

①.获取带泛型的类的类型

Class lstUClazz = List
.class

②获取局部变量泛型的类型

List
listUser = new ArrayList
();Type genType = listUser.getClass().getClass().getGenericSuperclass();Class templatClazz = null;if(ParameterizedType.class.isInstance(genType){ //无法获取到User类,或者可能获取到错误的类型,如果有同名且不带包名的泛型存在 ParameterizedType parameterizedType = (ParameterizedType) genType; templatClazz = (Class) parameterizedType.getActualTypeArguments()[0];}

 

那么,如何才能获取到泛型的类型

①.必须具有真实类型的存在

②.泛型的类型是明确的如(List<User>是明确的,List<T>是不明确的)

满足以上两点,我们就可以获取泛型的类型了

 

1.通过继承方式,明确类型,然后获取泛型类

public abstract class JdbcDaoSupport
{ protected JdbcDaoSupport() { } public Class getTempalteType() { Class
clazz = (Class
) ((ParameterizedType) getClass() .getGenericSuperclass()).getActualTypeArguments()[0]; return clazz; }}
public class UserDao extends JdbcDaoSupport
{}
public class Test{       public static void main(String[] args)       {           UserDao dao = new UserDao();           Class clazz = dao.getTemplateType();           System.out.println(clazz.getName());  //输出 xxx.xxx.User       }}

2.获取类属性的泛型类型

public class Test extends ClassA
{ private List
list; private Map
map; /*** * 获取List中的泛型 */ public static void testList() throws NoSuchFieldException, SecurityException { Type t = Test.class.getDeclaredField("list").getGenericType(); if (ParameterizedType.class.isAssignableFrom(t.getClass())) { for (Type t1 : ((ParameterizedType) t).getActualTypeArguments()) { System.out.print(t1 + ","); } System.out.println(); } } /*** * 获取Map中的泛型 */ public static void testMap() throws NoSuchFieldException, SecurityException { Type t = Test.class.getDeclaredField("map").getGenericType(); if (ParameterizedType.class.isAssignableFrom(t.getClass())) { for (Type t1 : ((ParameterizedType) t).getActualTypeArguments()) { System.out.print(t1 + ","); } System.out.println(); } } public static void main(String args[]) throws Exception { System.out.println(">>>>>>>>>>>testList>>>>>>>>>>>"); testList(); System.out.println("<<<<<<<<<<
<<<<<<<<<<<\n"); System.out.println(">>>>>>>>>>>testMap>>>>>>>>>>>"); testMap(); System.out.println("<<<<<<<<<<
<<<<<<<<<<<\n"); System.out.println(">>>>>>>>>>>testClassA>>>>>>>>>>>"); new Test().testClassA(); System.out.println("<<<<<<<<<<
<<<<<<<<<<<"); } }

3.获取局部变量的泛型的类型

List
lst = new ArrayList
(){};Type genType = listUser.getClass().getClass().getGenericSuperclass();Class templatClazz = null;if(ParameterizedType.class.isInstance(genType){ ParameterizedType parameterizedType = (ParameterizedType) genType; templatClazz = (Class) parameterizedType.getActualTypeArguments()[0];}

 

实际上,我们发现,能获取到泛型的类型实际上都是进行了“继承”。当然如果能熟练运用上述技巧,可以做很多事情,比如开源项目Gson中的TypeToken就是利用上述技巧,实现json与复杂类型的转换的。

 

很多情况下,Class被用来当作参数,我们其实可以将带泛型的类作为参数传入

我们一般为了方便,很少去特定定义一个类,因此,我们需要使用如下方式了。

Class clz = new ArrayList
(){}.getClass();

例子

class JsonToObjectUtil {	public static  
T jsonToObject(Class
clz,List
jsonList){ Type genType = clz.getClass().getGenericSuperclass(); Class templatClazz = null; if(ParameterizedType.class.isInstance(genType)); { ParameterizedType parameterizedType = (ParameterizedType) genType; templatClazz = (Class) parameterizedType.getActualTypeArguments()[0]; } List
lst = new ArrayList(); /*****/ if(templatClazz!=null && jsonList!=null) { for (String str : jsonList) { Gson gson = new Gson(); Object fromJson = gson.fromJson(str, templatClazz); lst.add(fromJson); } } /*****/ return (T) lst; } public static void main(String[] args) { List
jsonList = null; //略去一部分填充jsonList的逻辑 Class superClazz = new ArrayList
(){}.getClass(); List jsonToObject = JsonToObjectUtil.jsonToObject(superClazz, jsonList); } }

 

 

转载于:https://my.oschina.net/ososchina/blog/888090

你可能感兴趣的文章
高位缩量横盘的实战价值
查看>>
DataStage V7.5 下载
查看>>
notepad++ 自动换行
查看>>
领导无形,管理有道
查看>>
免费的.NET混淆和反编译工具
查看>>
6410裸机程序卡死
查看>>
SQL Server 2012安装Adventure Works数据库
查看>>
WPF 判断是否为设计(Design)状态
查看>>
表达式求值、表达式转二叉树
查看>>
watir查看编码格式
查看>>
GateWay程序分析_主函数_02整体流程
查看>>
javascript数组元素的添加、删除与插入以及参数数组的使用
查看>>
TransactionScope 之分布式配置
查看>>
最近工作有点不在状态,笔记也没状态
查看>>
Cmake Error: your compiler "cl" was not Found .etc
查看>>
zabbix监控
查看>>
构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(20)-权限管理系统-根据权限获取菜单...
查看>>
设计模式(六):Singleton 单件模式 -- 创建型模式
查看>>
delphi webbrowser 经常用法演示样例
查看>>
018 关联映射文件中<class>标签中的lazy(懒加载)属性
查看>>