- 浏览: 990839 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (1441)
- 软件思想&演讲 (9)
- 行业常识 (250)
- 时时疑问 (5)
- java/guava/python/php/ruby/R/scala/groovy (213)
- struct/spring/springmvc (37)
- mybatis/hibernate/JPA (10)
- mysql/oracle/sqlserver/db2/mongdb/redis/neo4j/GreenPlum/Teradata/hsqldb/Derby/sakila (268)
- js/jquery/jqueryUi/jqueryEaseyUI/extjs/angulrJs/react/es6/grunt/zepto/raphael (81)
- ZMQ/RabbitMQ/ActiveMQ/JMS/kafka (17)
- lucene/solr/nuth/elasticsearch/MG4J (167)
- html/css/ionic/nodejs/bootstrap (19)
- Linux/shell/centos (56)
- cvs/svn/git/sourceTree/gradle/ant/maven/mantis/docker/Kubernetes (26)
- sonatype nexus (1)
- tomcat/jetty/netty/jboss (9)
- 工具 (17)
- ETL/SPASS/MATLAB/RapidMiner/weka/kettle/DataX/Kylin (11)
- hadoop/spark/Hbase/Hive/pig/Zookeeper/HAWQ/cloudera/Impala/Oozie (190)
- ios/swift/android (9)
- 机器学习&算法&大数据 (18)
- Mesos是Apache下的开源分布式资源管理框架 (1)
- echarts/d3/highCharts/tableau (1)
- 行业技能图谱 (1)
- 大数据可视化 (2)
- tornado/ansible/twisted (2)
- Nagios/Cacti/Zabbix (0)
- eclipse/intellijIDEA/webstorm (5)
- cvs/svn/git/sourceTree/gradle/jira/bitbucket (4)
- jsp/jsf/flex/ZKoss (0)
- 测试技术 (2)
- splunk/flunm (2)
- 高并发/大数据量 (1)
- freemarker/vector/thymeleaf (1)
- docker/Kubernetes (2)
- dubbo/ESB/dubboX/wso2 (2)
最新评论
JAVA 反射的应用还是比较多,这里会对反射的一些原理进行介绍,然后我们才知道如何使用和优化。至于反射的使用介绍,这里就不在过多叙述了,API 上都介绍得有。
要了解JAVA 反射的原理,我们还得对类在虚拟机中的一些知识做简要介绍...
一、类文件的结构:
1.1 虚拟机加载Class文件过程:
在JVM 类加载机制的博客里面我介绍过整体流程,这里仅仅介绍加载时相关部分。
在我们启动一个类,或者其他方式加载一个类的时候,会通过类的全限定名获取该类的二进制流,然后将字节流所代表的的静态存储结构转化成方法区的运行时数据结构,然后会生成一个代表该类的java.lang.Class 对象,作为在方法区这个类的访问入口。也就是说只要完成了这一步骤,那么通过这个入
口我们就可以访问里面的存储好的数据结构信息了。而且动态加载的时候,会先进行查找,该类是否存在,
存在了就不会再加载了,保持一份。
class 文件是一组以8位字节为基础单位的二进制流,各个数据项目按严格的顺序紧凑的排列在Class文
件中,里面的信息主要描述以下信息:
1.版本号:主版本号和次版本号
2.常量池:主要存放字面量(Literal)和符号引用(references)
2.1 字面量:文本字符串、final 类型的常量值 等
2.2 符号引用:
a.类和接口的全限定名字
b.字段描述和描述符
c.方法的名称和描述
3.访问标志:
a.是类还是接口
b.是否是public 等类型
c.是否是abstract ,是否被声明为final 等标志
4.类索引、父类索引和接口索引集合
a.类索引:确定这个类的全限定名
b.父类索引:确定父类的全限定名
c.接口索引集合:作为入口,作为一个计数器
5.字段表集合:
包括信息有字段作用域(public,private等修饰符)、是实例变量还是类变量(static)、可变性 (final)、并发可见性(volatile)、可否被序列化(transient)等信息
6.方法集合:
包括访问标志、名称索引、描述符索引、属性表集合。
7.其他:包括属性表集合、Code 属性(指令) 等其他这里暂时不过多介绍,详细请看虚拟机的书籍。
二、反射概念:
通过上面简单的介绍,相信大家了解了我们的Class 文件在加载到JVM 里面之后,实际存放的信息有很
多,而且上面介绍的都是大家有一定了解的,比如 方法 、属性 等等,那么反射是什么呢?
所谓反射是JAVA 语言允许在 运行时拥有一种自审的能力,也就是说JVM 允许代码在运行期间可以获得
类的内部信息,简单的说我们可以在程序运行期间获得刚才我们介绍的类里面的信息。
2.1 反射的常用方法:
a.forName(String className) :
返回与带有给定字符串名的类或接口相关联的 Class 对象。
b.forName(String name, boolean initialize, ClassLoader loader) :
使用给定的类加载器,返回与带有给定字符串名的类或接口相关联的 Class 对象。
c.getAnnotation(Class<A> annotationClass)
如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
d.getAnnotations()
返回此元素上存在的所有注释。
e.getConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
f.getDeclaredField(String name)
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
g.getDeclaredMethod(String name, Class<?>... parameterTypes)
返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
这里我就不累赘了,仅仅引入性的介绍几个,更多的可以去看看API
三、反射的基本使用:这里我们写一个简单类,模拟常见的功能。
Java代码 复制代码 收藏代码
1. public class Test {
2.// 构造方法
3.public Test() {
4.System.out.println("无参数构造");
5.}
6.public Test(String str) {
7.System.out.println("有参构造:"+str);
8.}
9.public void test(){
10.System.out.println("普通测试方法:");
11.}
12.public static void staticTest(){
13.System.out.println("静态测试方法");
14.}
15.// 基本属性
16.private Integer number;
17.public String name = "张三";
18. }
1.类加载:
Java代码 复制代码 收藏代码
1. public static void main(String[] args) throws Exception {
2.Class<?> c = Class.forName("com.Test");
3.// 这里加载类,会调toString 方法, 打印类型,和getName 方法
4.// 同时发现类已经存在,说明加载成功
5.// 这里常常我们用来动态加载一个类,比如再获得JDBC 连接的时候,
6.// 我们可以动态的获得不通厂商的连接:Class.forName("xxx.oracle/mysql")
7.System.out.println("类信息:"+c);
8.// 同时这里可以直接这只加载器实现:Class.forName(name, initialize, loader)
9.}
2 获得方法并且调用:
Java代码 复制代码 收藏代码
1. public static void main(String[] args) throws Exception {
2.Class<?> c = Class.forName("com.Test");
3.// 这个是获得指定方法,我们先获得普通方法
4.Method m = c.getMethod("test");
5.// 这里执行会失败了,因为我们们的类没进行实例化
6.// m.invoke(c);
7.// 这样就不会,这里使用了默认的构造
8.m.invoke(c.newInstance());
9.// 但是静态方法不用实例化就可以
10.Method m2 = c.getMethod("staticTest");
11.m2.invoke(c);
12.// 当然我们还能获得所有的方法信息
13.// 获得该类所有方法
14.c.getDeclaredMethods();
15.// 获得包括继承的类的所有方法
16.c.getMethods();
17.}
3.获得字段信息:
Java代码 复制代码 收藏代码
1.public static void main(String[] args) throws Exception {
2.Class<?> c = Class.forName("com.Test");
3.// 私有字段是无法通过公有方式访问
4.// Field f1 = c.getField("number");
5.// public 字段是可以直接访问
6.Field f = c.getField("name");
7.System.out.println(f);
8.
9.
10.// 这是赋值,必须先获得对象实例,可以为字段赋值
11.Object o = c.newInstance();
12.f.set(o, "2");
13.System.out.println(f.get(o));
14.// 其他方法,和获取method 差不多
15.}
关于构造器,权限等这些就可以看API,这里仅仅介绍。
4.其他应用:
反射运用得很多,比如我们熟悉的hibernate、spring、以及其他的orm 框架都需要用到。
这里我们模拟hibernate 的实现,来完成对象的保存操作。
// 这是我们模拟的实体bean
Java代码 复制代码 收藏代码
1.// 这是我们模拟的实体bean
2.public class Bean {
3. private Integer id;
4. private String name;
5. private String password;
6. public Integer getId() {
7. return id;
8. }
9. public void setId(Integer id) {
10. this.id = id;
11. }
12. public String getName() {
13. return name;
14. }
15. public void setName(String name) {
16. this.name = name;
17. }
18. public String getPassword() {
19. return password;
20. }
21. public void setPassword(String password) {
22. this.password = password;
23. }
24.}
Java代码 复制代码 收藏代码
1.import java.lang.reflect.Field;
2.import java.lang.reflect.Method;
3.
4.// 这是我们的测试
5.public class Test {
6. public static void main(String[] args) {
7. // 1. 首先我们创建一个bean,模拟从前端获取的数据
8. Test t = new Test();
9. Bean bean = t.getBean();
10. // 2.生成我们需要的SQL 并设值
11. t.save(bean);
12. }
13.
14. private Bean getBean(){
15. // 模拟用反射实现
16. Bean bean = null;
17. try {
18. Class c = Class.forName("Bean");
19. bean = (Bean) c.newInstance();
20. // 私有字段无法访问,我们通过方法赋值
21. Method m1 = c.getDeclaredMethod("setId",Integer.class);
22. Method m2 = c.getDeclaredMethod("setName",String.class);
23. Method m3 = c.getDeclaredMethod("setPassword",String.class);
24. m1.invoke(bean, 1);
25. m2.invoke(bean, "admin");
26. m3.invoke(bean, "123456");
27. } catch (Exception e) {
28. e.printStackTrace();
29. }
30. return bean;
31. }
32.
33. // 假设我们的表 就是 BEAN
34. private void save(Bean bean){
35. Field[] fields = Bean.class.getDeclaredFields();
36. StringBuffer sb = new StringBuffer("INSERT INTO BEAN VALUES");
37. sb.append(getInsertStr(fields.length));
38. // 这里我们可以看到SQL 已经生成
39. System.out.println(sb);
40. // 这里就是我们的JDBC 根据字段名字赋值 的操作了。
41. // 当然hibernate 写得肯定会复杂很多,但是基本原理不变
42.
43. }
44.
45. private String getInsertStr(int fields){
46. StringBuffer sb = new StringBuffer("(");
47. for(int i = 0;i<fields;i++){
48. sb.append("?,");
49. }
50. sb.delete(sb.length()-1,sb.length());
51. sb.append(")");
52. return sb.toString();
53. }
54.}
在spring 里面,在介绍过生成代理类,也就是AOP 的地方也用过,这里也就不多说了。
小结:
1.这里介绍了反射的基本运用,以及一些相关原理的东西,还没真正深入
2.反射给了我们很大的灵活,但是同时很多错误只能到运行期间才能发现,使用要多注意。
3.反射提供灵活的同时,也牺牲了性能,在JDK1.6+ 版本,反射的一般调用,比直接调用慢2倍左右。
性能这一块后面再研究,再招优化的方案。
要了解JAVA 反射的原理,我们还得对类在虚拟机中的一些知识做简要介绍...
一、类文件的结构:
1.1 虚拟机加载Class文件过程:
在JVM 类加载机制的博客里面我介绍过整体流程,这里仅仅介绍加载时相关部分。
在我们启动一个类,或者其他方式加载一个类的时候,会通过类的全限定名获取该类的二进制流,然后将字节流所代表的的静态存储结构转化成方法区的运行时数据结构,然后会生成一个代表该类的java.lang.Class 对象,作为在方法区这个类的访问入口。也就是说只要完成了这一步骤,那么通过这个入
口我们就可以访问里面的存储好的数据结构信息了。而且动态加载的时候,会先进行查找,该类是否存在,
存在了就不会再加载了,保持一份。
class 文件是一组以8位字节为基础单位的二进制流,各个数据项目按严格的顺序紧凑的排列在Class文
件中,里面的信息主要描述以下信息:
1.版本号:主版本号和次版本号
2.常量池:主要存放字面量(Literal)和符号引用(references)
2.1 字面量:文本字符串、final 类型的常量值 等
2.2 符号引用:
a.类和接口的全限定名字
b.字段描述和描述符
c.方法的名称和描述
3.访问标志:
a.是类还是接口
b.是否是public 等类型
c.是否是abstract ,是否被声明为final 等标志
4.类索引、父类索引和接口索引集合
a.类索引:确定这个类的全限定名
b.父类索引:确定父类的全限定名
c.接口索引集合:作为入口,作为一个计数器
5.字段表集合:
包括信息有字段作用域(public,private等修饰符)、是实例变量还是类变量(static)、可变性 (final)、并发可见性(volatile)、可否被序列化(transient)等信息
6.方法集合:
包括访问标志、名称索引、描述符索引、属性表集合。
7.其他:包括属性表集合、Code 属性(指令) 等其他这里暂时不过多介绍,详细请看虚拟机的书籍。
二、反射概念:
通过上面简单的介绍,相信大家了解了我们的Class 文件在加载到JVM 里面之后,实际存放的信息有很
多,而且上面介绍的都是大家有一定了解的,比如 方法 、属性 等等,那么反射是什么呢?
所谓反射是JAVA 语言允许在 运行时拥有一种自审的能力,也就是说JVM 允许代码在运行期间可以获得
类的内部信息,简单的说我们可以在程序运行期间获得刚才我们介绍的类里面的信息。
2.1 反射的常用方法:
a.forName(String className) :
返回与带有给定字符串名的类或接口相关联的 Class 对象。
b.forName(String name, boolean initialize, ClassLoader loader) :
使用给定的类加载器,返回与带有给定字符串名的类或接口相关联的 Class 对象。
c.getAnnotation(Class<A> annotationClass)
如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
d.getAnnotations()
返回此元素上存在的所有注释。
e.getConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
f.getDeclaredField(String name)
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
g.getDeclaredMethod(String name, Class<?>... parameterTypes)
返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
这里我就不累赘了,仅仅引入性的介绍几个,更多的可以去看看API
三、反射的基本使用:这里我们写一个简单类,模拟常见的功能。
Java代码 复制代码 收藏代码
1. public class Test {
2.// 构造方法
3.public Test() {
4.System.out.println("无参数构造");
5.}
6.public Test(String str) {
7.System.out.println("有参构造:"+str);
8.}
9.public void test(){
10.System.out.println("普通测试方法:");
11.}
12.public static void staticTest(){
13.System.out.println("静态测试方法");
14.}
15.// 基本属性
16.private Integer number;
17.public String name = "张三";
18. }
1.类加载:
Java代码 复制代码 收藏代码
1. public static void main(String[] args) throws Exception {
2.Class<?> c = Class.forName("com.Test");
3.// 这里加载类,会调toString 方法, 打印类型,和getName 方法
4.// 同时发现类已经存在,说明加载成功
5.// 这里常常我们用来动态加载一个类,比如再获得JDBC 连接的时候,
6.// 我们可以动态的获得不通厂商的连接:Class.forName("xxx.oracle/mysql")
7.System.out.println("类信息:"+c);
8.// 同时这里可以直接这只加载器实现:Class.forName(name, initialize, loader)
9.}
2 获得方法并且调用:
Java代码 复制代码 收藏代码
1. public static void main(String[] args) throws Exception {
2.Class<?> c = Class.forName("com.Test");
3.// 这个是获得指定方法,我们先获得普通方法
4.Method m = c.getMethod("test");
5.// 这里执行会失败了,因为我们们的类没进行实例化
6.// m.invoke(c);
7.// 这样就不会,这里使用了默认的构造
8.m.invoke(c.newInstance());
9.// 但是静态方法不用实例化就可以
10.Method m2 = c.getMethod("staticTest");
11.m2.invoke(c);
12.// 当然我们还能获得所有的方法信息
13.// 获得该类所有方法
14.c.getDeclaredMethods();
15.// 获得包括继承的类的所有方法
16.c.getMethods();
17.}
3.获得字段信息:
Java代码 复制代码 收藏代码
1.public static void main(String[] args) throws Exception {
2.Class<?> c = Class.forName("com.Test");
3.// 私有字段是无法通过公有方式访问
4.// Field f1 = c.getField("number");
5.// public 字段是可以直接访问
6.Field f = c.getField("name");
7.System.out.println(f);
8.
9.
10.// 这是赋值,必须先获得对象实例,可以为字段赋值
11.Object o = c.newInstance();
12.f.set(o, "2");
13.System.out.println(f.get(o));
14.// 其他方法,和获取method 差不多
15.}
关于构造器,权限等这些就可以看API,这里仅仅介绍。
4.其他应用:
反射运用得很多,比如我们熟悉的hibernate、spring、以及其他的orm 框架都需要用到。
这里我们模拟hibernate 的实现,来完成对象的保存操作。
// 这是我们模拟的实体bean
Java代码 复制代码 收藏代码
1.// 这是我们模拟的实体bean
2.public class Bean {
3. private Integer id;
4. private String name;
5. private String password;
6. public Integer getId() {
7. return id;
8. }
9. public void setId(Integer id) {
10. this.id = id;
11. }
12. public String getName() {
13. return name;
14. }
15. public void setName(String name) {
16. this.name = name;
17. }
18. public String getPassword() {
19. return password;
20. }
21. public void setPassword(String password) {
22. this.password = password;
23. }
24.}
Java代码 复制代码 收藏代码
1.import java.lang.reflect.Field;
2.import java.lang.reflect.Method;
3.
4.// 这是我们的测试
5.public class Test {
6. public static void main(String[] args) {
7. // 1. 首先我们创建一个bean,模拟从前端获取的数据
8. Test t = new Test();
9. Bean bean = t.getBean();
10. // 2.生成我们需要的SQL 并设值
11. t.save(bean);
12. }
13.
14. private Bean getBean(){
15. // 模拟用反射实现
16. Bean bean = null;
17. try {
18. Class c = Class.forName("Bean");
19. bean = (Bean) c.newInstance();
20. // 私有字段无法访问,我们通过方法赋值
21. Method m1 = c.getDeclaredMethod("setId",Integer.class);
22. Method m2 = c.getDeclaredMethod("setName",String.class);
23. Method m3 = c.getDeclaredMethod("setPassword",String.class);
24. m1.invoke(bean, 1);
25. m2.invoke(bean, "admin");
26. m3.invoke(bean, "123456");
27. } catch (Exception e) {
28. e.printStackTrace();
29. }
30. return bean;
31. }
32.
33. // 假设我们的表 就是 BEAN
34. private void save(Bean bean){
35. Field[] fields = Bean.class.getDeclaredFields();
36. StringBuffer sb = new StringBuffer("INSERT INTO BEAN VALUES");
37. sb.append(getInsertStr(fields.length));
38. // 这里我们可以看到SQL 已经生成
39. System.out.println(sb);
40. // 这里就是我们的JDBC 根据字段名字赋值 的操作了。
41. // 当然hibernate 写得肯定会复杂很多,但是基本原理不变
42.
43. }
44.
45. private String getInsertStr(int fields){
46. StringBuffer sb = new StringBuffer("(");
47. for(int i = 0;i<fields;i++){
48. sb.append("?,");
49. }
50. sb.delete(sb.length()-1,sb.length());
51. sb.append(")");
52. return sb.toString();
53. }
54.}
在spring 里面,在介绍过生成代理类,也就是AOP 的地方也用过,这里也就不多说了。
小结:
1.这里介绍了反射的基本运用,以及一些相关原理的东西,还没真正深入
2.反射给了我们很大的灵活,但是同时很多错误只能到运行期间才能发现,使用要多注意。
3.反射提供灵活的同时,也牺牲了性能,在JDK1.6+ 版本,反射的一般调用,比直接调用慢2倍左右。
性能这一块后面再研究,再招优化的方案。
发表评论
-
20180222积累
2018-02-22 09:34 4321. mybatis如何通过接口查找对应的mapper. ... -
20180208积累
2018-02-08 10:28 409临时表与永久表相似,但临时表存储在 tempdb 中,当不 ... -
行业应用
2018-01-30 16:30 437git clone的时候用上面那个IP地址,下面栏中的不能 ... -
SQLite 数据库
2018-01-29 22:57 717android: SQLite创建数据 ... -
java里面获取map的key和value的方法
2018-02-01 11:29 2074获取map的key和value的方法分为两种形式: ma ... -
Eclipse中Maven WEB工程tomcat项目添加调试以及项目发布细节记录
2018-02-23 21:11 673一、建立一个maven WEB项目 1、file-&g ... -
错误:HttpServlet was not found on the Java
2018-02-23 21:12 334我们在用Eclipse进行Java web ... -
使用 java8 实现List到Array的转换
2018-02-23 21:13 2865开发中需要调用第三方的库,有些 API 的入参要求是 do ... -
Java8 利用Lambda处理List集合
2018-01-11 09:58 5562Java 8新增的Lambda表达式,我们可以很方便地并行操 ... -
java中string与json互相转化
2018-01-11 09:40 1024在Java中socket传输数据时,数据类型往往比较难选择。 ... -
JSON 数据格式
2018-01-11 09:37 417JSON(JavaScript Object Notatio ... -
java怎么读取json格式的数据
2018-01-11 09:46 1018java可以使用JSONObject和JSONArray来操作 ... -
Java8-如何将List转变为逗号分隔的字符串
2018-01-10 10:13 1919Converting a List to a String ... -
eclipse maven 打war包的两种方式
2018-02-23 21:25 650第一种:利用pom.xml文件打包。 右键pom.xml ... -
Annotation(三)——Spring注解开发
2018-02-28 09:21 380Spring框架的核心功能IoC(Inversion o ... -
Spring自定义注解
2018-02-28 09:32 528java注解:附在代码中的一些元信息,用于在编译、运行时起 ... -
Java项目
2018-01-08 10:56 0这两种解决办法已经能完全解决问题,不过值得注意的一点是,我 ... -
解决Eclipse建立Maven项目后无法建立src/main/java资源文件夹的办法
2018-03-22 10:41 1091在Eclipse中建立好一个Maven项目后,如果Java ... -
Java @override报错的解决方法
2018-01-07 12:56 0有时候Java的Eclipse工程换一台电脑后编译总是@ove ... -
Java 8 配置Maven-javadoc-plugin
2018-01-07 09:07 978在升级JDK至1.8之后,使用Maven-javadoc- ...
相关推荐
JAVA反射机制及应用例子.。。Reflection API
描述JAVA反射机制应用、举例。描述反射机制的具体实现及方法实现。
JAVA 反射机制应用JAVA 反射机制应用JAVA 反射机制应用JAVA 反射机制应用JAVA 反射机制应用JAVA 反射机制应用JAVA 反射机制应用
本篇文章主要介绍了Java反射机制及应用场景,反射机制是很多Java框架的基石。非常具有实用价值,需要的朋友可以参考下。
java的反射机制的应用实例,对反射的机制很好的理解!
近公司正在进行业务组件化进程,其中的路由实现用到了Java的反射机制,既然用到了想着好好学习总结一下,其实无论是之前的EventBus 2.x版本还是Retrofit、早期的View注解框架都或多或少的用到Java的反射机制。...
Java中,反射是一种强大的工具。它使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接。...这使反射成为构建灵活的应用的主要工具。但需注意的是:如果使用不当,反射的成本很高。
J2SE的反射机制高级应用J2SE的反射机制高级应用J2SE的反射机制高级应用J2SE的反射机制高级应用
java反射机制应用,文档中列举了使用java反射机制的各个应用场景,加以代码实例,使用学习非常方便。
关于java反射机制的很好的讲解,包括Java的反射机制(Reflection)、Class类、如何获得类的相关信息和运用,并且还有相应的练习,有助于更好地学习java反射机制
Qt 使用QMetaObject实现反射机制代码demo
java反射机制详解与应用
java反射机制的原理及在Android下的简单应用
介绍AOP动态代理很不错的一本技术书籍,里面又很多例子通俗易懂。
图解java反射机制及常用应用场景_字母哥博客
对java泛型以及反射机制进行原理和应用上的讲解,帮助初学者对这两个概念进行更轻松的掌握
介绍反射的基本原理和实现,以及所涉及到的类和方法,应用的场景
用反射机制改进的抽象工厂
Java反射机制在数据持久层轻量级ORM框架中的应用研究.pdf
java反射机制详解与应用.pdf