前一篇对泛型进行了一番总结,本篇就来说说与泛型有关的反射。
我在泛型篇中说到了泛型在JVM中是会被擦除的,不过擦除的类还是“残留”了一些泛型的痕迹。比如Person<T>类,虽然擦除掉了泛型<T>,但是通过反射机制是可以获得这些信息的,不光如此,Person类里面定义的泛型方法都可以通过反射获得。让我们用代码来验证一下。
在用代码验证之前,大象会对Person类稍微改造一下,增加一个泛型变量K以及一个泛型方法,其它的都保持不变。
publicclass Person<T, K extends Comparable<? super T> & Serializable>
extends SuperPerson<String> implements Handle<Date> {
......
publicstatic <T extends Comparable<? super T>> T max(List<? extends T> list){
Iterator<? extends T> it = list.iterator();
T result = it.next();
while(it.hasNext()){
T t = it.next();
if(t.compareTo(result) > 0)
result = t;
}
return result;
}
......
}
下面可以开始写代码了吗?别急,大象还想先把代码中用到的几个跟反射有关的API接口说明一下,这都是JDK5.0中为泛型新增的,然后还用到了一个JDK6.0提供的Modifier,它是一个枚举类型,可以表示类、方法或字段的修饰符。
Type
它是所有类型的公共接口。包括原始类型、参数化类型、数组类型、类型变量和基本类型。ParameterizedType, TypeVariable, WildcardType,GenericArrayType这四个接口都是它的子接口。
GenericDeclaration
这个接口Class、Method、Constructor都有实现,我们就是要用这个接口的getTypeParameters方法,它返回一个TypeVariable[]数组,这个数组里面就是我们定义的类型变量T和K,顺序与我们声明时一样。如果用循环语句将数组打印出来,你会发现只会输出T和K,这可不是我们想要的结果,那么想要获得预期的结果怎么办呢?请继续往下看。
TypeVariable
它表示类型变量。比如T,比如K extendsComparable<? superT> & Serializable,这个接口里面有个getBounds()方法,它用来获得类型变量上限的Type数组,如果没有定义上限,则默认设定上限为Object,请注意TypeVariable是接口,实际得到的是TypeVariableImpl实现类,下面几个接口都一样。
拿T和K来说明,T没有定义任何上限,所以它就有一个默认上限java.lang.Object,实际跟踪代码的时候你会发现T的bounds属性为空,只有在调用了getBounds()方法后,才会有一个Type[1]数组[class java.lang.Object]。而对于K来说,调用了getBounds方法后,得到的数组是[java.lang.Comparable<? super T>, interface java.io.Serializable],它们的类型却是不一样的,第1个是ParameterizedType,而第二个是Class
ParameterizedType
ParameterizedType表示参数化类型,就是上面说的java.lang.Comparable<? super T>,再比如List<T>,List<String>,这些都叫参数化类型。得到Comparable<? super T>之后,再调用getRawType()与getActualTypeArguments()两个方法,就可以得到声明此参数化类型的类(java.lang.Comparable)和实际的类型参数数组([? super T]),而这个? super T又是一个WildcardType类型。
WildcardType
它用来描述通配符表达式,上面返回的? super T正好是这个类型。然后调用getUpperBounds()上限和getLowerBounds()下限这两个方法,获得类型变量?的限定类型(上下限),对于本例的通配符(?),它的上限为java.lang.Object,下限为T
通过上面几个接口的分析,可以将Person类的泛型参数都解析出来,那么Person的超类以及实现的接口该怎么处理呢?Class类里面同样在1.5版本加入了getGenericSuperclass()与getGenericInterfaces()两个方法,用于返回带参数化类型的超类与接口。
至此,通过上面这些接口和方法我们已经可以把class Person后面的代码都解析出来了,类里面的方法与解析类的泛型化参数类似,就不再赘述了。下图就是通过反射将定义的Person类打印出来的结果。
本文主要是想通过反射机制来验证在JVM虚拟机中获得泛型的一些知识。一般实际使用的时候多数是通过反射获取超类的泛型,或者通过反射调用方法,读取/设置属性值等等这些功能,最下面有示例源码的下载。
反 射虽然很有用处,但也不能滥用。首先用了反射就没办法在编译时进行类型检查,而且反射的代码比较复杂不容易阅读,不过好在现在有很多已经封装好的反射工具 类,帮我们做了不少这方面的工作。最后也是最重要的一点是因为,使用反射会有一定的性能损耗,就是说会比直接调用方法要慢,至于慢多少,这个不好说,但肯 定会慢,因此除非有必要,大象建议在一般情况下首先考虑用接口来代替反射。
以上这些都是本篇关于泛型相关的反射介绍,算是一个入门知识吧,有什么不对的,或不完善的地方,还请各位指出来,谢谢!
- 浏览: 129632 次
文章分类
- 全部博客 (219)
- spring (27)
- log (2)
- setupfactory (1)
- java (89)
- database (14)
- strust2 (1)
- java memcache (10)
- 网络协议 (1)
- hibernate (9)
- jms (4)
- tomcat (12)
- spring security (2)
- mybatis (7)
- web service (4)
- 项目总结 (4)
- ant (1)
- Linux (1)
- 架构 (2)
- 资料 (2)
- redis (12)
- maven (3)
- jvm (3)
- wechat (2)
- jdk 源码 (1)
- 面试 (9)
- java 序列化 (0)
- 数据结构 (1)
- netty (1)
- 22 (0)
最新评论
-
yszzu:
java -cp "lib/*" 自动搜索 ...
JAVA CP命令 -
smallbug_vip:
能不能受累从百度上把图片缓存本地然后传给iteye。
vpn的实现原理 -
xiaoxuan_blog:
...
getResource()和getResourceAsStream以及路径问题
发表评论
-
java 动态编译和加载类
2016-04-20 10:03 606import javax.tools.*; imp ... -
Redis内存使用优化与存储
2016-04-09 11:21 775传统MySQL+ Memcached架构遇到的问题 实际M ... -
反应器(Reactor)模式
2016-04-04 20:28 270概述 Java NIO非堵塞技 ... -
系列技术 教程博客地址
2016-04-04 11:30 3931: 阮一峰 技术博客 http://www.rua ... -
69道Spring面试题和答案
2016-03-31 21:46 524目录 Spring 概述 依赖 ... -
IO基础入门之I/O多路复用技术
2016-03-29 13:18 408在I/O编程过程中,当需 ... -
再谈select, iocp, epoll,kqueue及各种I/O复用机制
2016-03-29 12:51 580首先,介绍几种常见的I/O模型及其区别,如下: bl ... -
动态编辑加载自定义类
2016-03-17 23:39 426package test; import java.io. ... -
Java动态代理机制详解(JDK和CGLIB,Javassist,ASM)
2016-03-17 23:10 1049lass文件简介及加载 Java编译器编译好 ... -
Java IO vs NIO vs AIO vs 协议Servlet 3.0 以及NIO的框架
2016-03-12 17:12 516nio(new io)从jdk1.4就有了,但是一直没用过,今 ... -
亿级Web系统搭建——单机到分布式集群
2016-03-06 21:23 422当一个Web系统从日访问量10万逐步增长到1000万,甚至超 ... -
Web系统大规模并发——电商秒杀与抢购
2016-03-06 21:12 443电商的秒杀和抢购,对我们来说,都不是一个陌生的东西。然而,从 ... -
浏览器 HTTP 协议缓存机制详解
2016-03-06 17:53 442最近在准备优化日志请求时遇到了一些令人疑惑的问题,比如为什么 ... -
SQL 优化经验总结34条
2016-03-05 12:08 532(1) 选择最有效率的 ... -
java 知识 点
2016-03-02 13:40 430面试要点 了解一下教 ... -
Java开发中的23种设计模式详解(转)
2016-03-01 14:14 429设计模式(Design pattern ... -
设计模式六大原则
2016-02-29 13:24 459目录: 设计模式六大原则(1):单一职责原则 设计模式 ... -
Java中的IO流系统详解
2016-02-28 18:13 523摘要: Java 流在处理上分为字符流和字节流。字符流处理 ... -
40个Java集合类面试题和答案
2016-02-27 22:06 5051.Java集合框架是什么? ... -
CAS实现SSO单点登录原理
2016-02-27 11:25 4201. CAS 简介 1.1. What ...
相关推荐
java的基于泛型+反射的通用DAO例子,原创,没事写着玩的,请多指教哈。。。
泛型 反射 概念 方法 使用
对java泛型以及反射机制进行原理和应用上的讲解,帮助初学者对这两个概念进行更轻松的掌握
同时,因为反射会带来性能损失,因此,可根据自己需求,针对每个类型轻松在两种模式之前切换,本例源码,测试实例俱全,而且代码浅显易懂,只要对泛型、反射、三层架构有一定了解的人都能轻松学习
详细介绍了JAVA泛型和反射,对学习JAVA很有帮助哦!!!!
java泛型+反射使用的源码,比较详细,欢迎下载
C#泛型、反射实例,分层,自动生成sql语句
反射和泛型是一种重要的解决途径。 此代码是一个生成泛型对象的类。 比如: Pool<Point> pool = new Pool(){}; Point p = pool.get(x, y); //在此构造Point对象 ... pool.put(p); 希望能帮助那些为查找泛型构造器、...
鉴于使用三层架构的过程中,数据库变动造成大量代码改动的问题,特意对三层架构进行了改进,数据库变动只需要简单修改model即可,同时,因为反射会带来性能损失,因此,可根据自己需求,针对每个类型轻松在两种模式...
j2ee泛型和反射有趣的集合j2ee泛型和反射有趣的集合j2ee泛型和反射有趣的集合j2ee泛型和反射有趣的集合
Java泛型和反射机制
java反射全解(反射原理+反射API详解+反射与数组+反射与泛型+反射源码与性能开销+反射优缺点+反射与内省)
C#泛型和反射联合使用的实例代码,绝对正常运行,含义注释,有问题和建议可留言!
在C#中通过反射操作一个List泛型。。
徒手写的一个Dao层,与greenDao思想大致相同,有不明白的欢迎大家提问咯
使用泛型和反射,打造我们的完美实体基类 ,非常详细 !
先说一下遇到的问题:通过使用GSON泛型进行报文转换的时候想要对部分关键字段加密,发现在封装好的方法中,对个别字段的加密满足不了。 解决过程:首先通过反射获取到bean下的对象名称。 对象名称获取到了之后需要...
NULL 博文链接:https://840198532-qq-com.iteye.com/blog/1491352