java运行时获得泛型类型
引言
众所周知,java泛型最重要的特征是泛型擦除,所有泛型在编译时会转换成Object所以在java中运行时无法获得泛型的类型。
但是其实以上的规则是针对方法的内部变量的,如果是其他形式的泛型其实是可以获得内部类型的
类内部成员变量
public static void main(String[] arg) throws NoSuchFieldException, SecurityException{
Field f=Pojo.class.getField("list"); //反射获得泛型成员变量
System.out.println(f.getGenericType()); //输出成员变量类型
Type[] type=((ParameterizedType)f.getGenericType()).getActualTypeArguments(); //获得泛型的所有泛型参数
for(Type t:type){
System.out.println(t); //遍历输出各个参数
}
}
public static class Pojo{
public List<String> list; //泛型成员变量
}
-----------输出-------------
java.util.List<java.lang.String>
class java.lang.String
泛型父类/接口
public static void main(String[] arg) throws NoSuchFieldException, SecurityException{
List l=new ArrayList<String>(){}; //创建一个ArrayList内部类 注意这里后面加了{}是内部类而不是简单的arraylist
System.out.println(l.getClass().getGenericSuperclass()); //输出泛型父类
Type[] t2=((ParameterizedType)l.getClass().getGenericSuperclass()).getActualTypeArguments(); //获得泛型的所有泛型参数
for(Type t:t2){
System.out.println(t); //遍历输出各个参数
}
}
-----------输出-------------
java.util.ArrayList<java.lang.String>
class java.lang.String
这里的list是继承ArrayList<String>的子类,其父类是ArrayList<String>,只有父类/父接口拥有泛型参数才可以获得对应的泛型参数,直接写new ArrayList<String>()的输出结果就会是
java.util.AbstractList<E>
E
就无法获得泛型类型
应用
看到这里来说下以上功能的用处,最常见的用处是用于数据解析,比如jackson
ObjectMapper mapper = new ObjectMapper();
map = mapper.readValue(input, new TypeReference<Map<String, Object>>(){});
就是通过实现TypeReference接口产生子类来传递泛型参数的(同样后面带着{})来告诉框架期望转换成什么样的对象
总结
JDK保存这些信息想必是因为类继承时会需要相应泛型的范围是否正确,在日常开发中需要通过泛型传递类型可以用本文的方法
- 泛型成员变量
- 泛型父类/接口
来实现。
java运行时获得泛型类型的更多相关文章
- java运行时跟编译时的区别,欢迎大家指正
个人博客地址:https://blog.csdn.net/qq_41907991 关于java运行时及编译时期的区别: 首先我们要了解编译以及运行的概念: 编译就是指,编译器帮你把源码翻译成机器能识别 ...
- java运行时内存模式学习
学习java运行时内存模式: 各区介绍: 方法区(线程共享):用于存放被虚拟机加载的类的元数据:静态变量,常量,以及编译和的代码(字节码),也称为永久代(所有该类的实例被回收,或者此类classLoa ...
- Jvm基础(1)-Java运行时数据区
最近在看<深入理解Java虚拟机>,里面讲到了Java运行时数据区,这是Jvm基本知识,把读书笔记记录在此.这些知识属于常识,都能查到的,如果我有理解不对的地方,还请指出. 首先把图贴上来 ...
- Java运行时内存
对于java程序员来说,并不必显示地对内存进行管理,一切都交给java虚拟机去做吧,而且,你也不一定做得比java虚拟机来得专业.好像所有内存管理都交给虚拟机去做就万事大吉了,但是,事实有时并非如此, ...
- 读书笔记-浅析Java运行时数据区
作为一个 Java 为主语言的程序员,我偶尔也需要 用 C/C++ 写程序,在使用时让我很烦恼的一件事情就是需要对 new 出来的对象进行 delete/free 操作,我老是担心忘了这件事情,从而导 ...
- Java运行时环境---内存划分
背景:听说Java运行时环境的内存划分是挺进BAT的必经之路. 内存划分: Java程序内存的划分是交由JVM执行的,而不像C语言那样需要程序员自己买单(C语言需要程序员为每一个new操作去配对del ...
- JVM发展史和Java运行时内存区域
目前三大主流JVM: Sun HotSpot:Sun于1997年收购Longview Technologies公司所得.Sun于2009年被Oracle收购. BEA JRockit:BEA于2002 ...
- JAVA运行时异常及常见的5中RuntimeExecption
最近在抽时间看面试题,很多面试题都提出了写出java常见的5个运行时异常.现在来总结一下, java运行时异常是可能在java虚拟机正常工作时抛出的异常. java提供了两种异常机制.一种是运行时异常 ...
- Java 内存管理、JVM 工作原理与 Java 运行时系统
Java 虚拟机规范中说明:所有的对象实例(all class instances)以及数组都要在堆上分配: the heap is the runtime data area from which ...
随机推荐
- 【.net 深呼吸】设置序列化中的最大数据量
欢迎收看本期的<老周吹牛>节目,由于剧组严重缺钱,故本节目无视频无声音.好,先看下面一个类声明. [DataContract] public class DemoObject { [Dat ...
- H5坦克大战之【玩家控制坦克移动2】
周一没有看圣诞大战,这几天比较忙也没有看赛后的报道,今天就先不扯NBA,随便扯扯自己.昨天在电脑里找东西的时候翻到以前兼职健身教练时的照片,思绪一下子回到学生时代,脑子久久换不过来.现在深深觉得健身和 ...
- .NET跨平台之运行与Linux上的Jexus服务器
谈及.NET跨平台,已经不是什么稀奇的事儿.今天我们就以Jexus服务器的部署为例.简单示范下.在这里,我用VMWare虚拟机来搭建Linux运行环境. Linux,我们选择CentOS7.大家可以前 ...
- 以向VS 程序打包集成自动写入注册表功能为例,介绍如何实现自由控制安装过程
最近由于项目部署时需要更灵活的控制程序安装的流程以及自定义安装行为,特意研究了一下VS程序打包,把解决办法和大家分享一下. 以VS2010为例: 这是一个已经设置好最基本的Visual Studio ...
- Redis简单案例(二) 网站最近的访问用户
我们有时会在网站中看到最后的访问用户.最近的活跃用户等等诸如此类的一些信息.本文就以最后的访问用户为例, 用Redis来实现这个小功能.在这之前,我们可以先简单了解一下在oracle.sqlserve ...
- Docker与CI持续集成/CD
背景 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制 ...
- 数据库设计中的Soft Delete模式
最近几天有点忙,所以我们今天来一篇短的,简单地介绍一下数据库设计中的一种模式——Soft Delete. 可以说,该模式毁誉参半,甚至有非常多的人认为该模式是一个Anti-Pattern.因此在本篇文 ...
- 用Maven部署war包到远程Tomcat服务器
过去我们发布一个Java Web程序通常的做法就是把它打成一个war包,然后用SSH这样的工具把它上传到服务器,并放到相应的目录里,让Tomcat自动去解包,完成部署. 很显然,这样做不够方便,且我们 ...
- STM32基于HAL库通过DMA读写SDIO
通过STM32CUBEMX生成DMA读写sdio的工程,再读写过程中总会卡死在DMA中断等待读写完成的while中,最终发现while等待的标志在SDIO的中断里置位的,而SDIO中断优先级如果小于或 ...
- 自定义tabBar
★★★★自定义tabBar★★★★★★★ Demo下载地址:https://github.com/marlonxlj/tabBarCustom.git 前言: 有的时候需求要对tabBar进行自定义的 ...