java之反射技术应用(二)

在上篇中就对java反射机制做了一个详尽的介绍,相信你对反射也应该有一些了解,这时候你可能会问,那反射究竟在我们日常开发中都会用在什么地方呢,

特别是一些初级人员更不禁要问,怎么我们平常好像不用反射也能够开发。

在这里要纠正一点,其实只要你在用框架做开发,那么你时时刻刻都在反射打交道,如果没有反射,根本就不会有所谓的框架,至于具体细节,

我们这里埋一个伏笔,后面将会做些介绍。


首先,我们这里出一道题

给你一个未知的DTO(数据传输对象),然后创建出一个新的对象,并把原来对象属性的值都给新的对象,我们这里姑且称为复制对象,

按照我们以前所具备的的知识,我们应该会这么做。

DTO  newObj = new DTO();

newObj.setXXX(old.getXXX());

可是不要忘记了一个关键词-“未知”,它有哪些属性,在编译期我们一无所知。你将如何实例化出一个它的对象,又如何调用它的方法。传进来的对象只有在运行期才能够知道。


这时候反射将会派上用场

大家一起看看代码具体怎么做的。

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. public Object copy(Object object) throws Exception{  
  2.     Class<?> clazz = object.getClass();  
  3.       
  4.     Object objectCopy = clazz.newInstance();  
  5.       
  6.     Field[] fields = clazz.getDeclaredFields();  
  7.       
  8.     for(int i=0;i<fields.length;i++){  
  9.         Field field = fields[i];  
  10.         String fieldName = field.getName();  
  11.         String firstLetter = fieldName.substring(0,1).toUpperCase();  
  12.           
  13.         String getMethodName = "get"+firstLetter+fieldName.substring(1);  
  14.         String setMethodName = "set"+firstLetter+fieldName.substring(1);  
  15.           
  16.         Method getMethod = clazz.getMethod(getMethodName, new Class[]{});  
  17.         Method setMethod = clazz.getMethod(setMethodName, new Class[]{field.getType()});  
  18.           
  19.         Object value = getMethod.invoke(object, new Object[]{});  
  20.           
  21.         setMethod.invoke(objectCopy, new Object[]{value});  
  22.     }  
  23.     return objectCopy;  
  24. }  
测试类

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. public static void main(String[] args) throws Exception {  
  2.     Customer customer = new Customer();  
  3.     customer.setAge(22);  
  4.     customer.setId(99L);  
  5.     customer.setName("hello");  
  6.     Customer customerCopy = (Customer)new ReflectTest().copy(customer);  
  7.     System.out.println(customerCopy.getId()+","+customerCopy.getAge()+","+customerCopy.getName());  
  8. }  

打印结果:

99,22,hello

我们先梳理一遍,拿到具体的DTO对象,我们就可以拿到与之对应的Class对象(每个对象都有个与之对应的Class对象),然后我们可以根据这个Class对象去实例化出一个新的DTO对象。给对象赋值肯定要用到set方法,取原来对象的值要用到get方法,那怎么调用到这些方法呢?学了前面一篇,我们应该知道只要知道方法名就可以调用此方法名的方法。至于都有哪些方法,这个就好说了,有哪些属性就有哪些与之对应的get、set方法,属性名,是可以遍历取到的,是不是水到渠成了呢。


反射可能用到的地方

       如果让你去写一个EXCEL导出工具类,不管是用POI还是JXL,你会怎么做?

       传进来的肯定会有一个list对象(List<T>),你肯定也知道要给每行单元格依次赋值,从每个T对象中取值放到对应的单元格中,取值自然而然会调用getXXX方法。

        可是既然是工具类,可不是只对一种类型的数据进行导出,可能是导出用户类表(User),也可能是商品列表(Goods),也可能是其它。难道我们要对每个不同类型的列表都去写一个导出嘛,这显然是不可能的。反射在这里就会起到至关重要的作用,不管什么类型的对象,不管其中有哪些属性,属性是什么类型,我们可以通过反射拿到,也能得到与之对应的所有get、set方法。


反射在Struts2框架中的应用

       学过struts2框架的同学应该都知道一点,在action中,只要给页面传过来的值,生成一个与之匹配的get、set方法,我们就能直接拿到值, 而不是需要使用request.getParameter("")的方式进行取值。

       那为什么这样就可以拿到值了呢,是谁给你赋好值了,你会说,书上说的,老师这么教的,这样就可以。确实这样可以拿到值,我们开发中多半也是这么干的,可你难道就没想过为什么会有值吗。

这里反射就有很大的功劳,它会依据你的所有set方法,然后匹配传值,这些都有框架在给你实例化action的时候完成。


反射在Hibernate框架中的应用

        hibernate众所周知是一个ORM框架,我们可以直接操作一个对象进行持久化,session,save(对象),那它的底层又是怎样实现的呢?

        这里我们温故下JDBC是如何往数据库插入条记录的,insert into student(name,ages,addr)  values (?,?,?)

        hibernate无论怎么做,最终肯定也还是要发出自己的sql语句,它只不过是对JDBC做了一个更好的封装,那它是怎么知道那些字段的,显而易见还是通过反射,当然具体hibernate的封装肯定是很复杂的,但肯定少不了反射。反射机制的作用就是能够找到字段、方法和已加载类的构造函数的信息,并且能够应用反射域、方法和构造函数去操作各自的属性。


反射在Spring框架中的应用

         spring两大核心是IOC和AOP,这两个都用到了反射机制,以及AOP甚至用到了反射相关的动态代理。

         spring依赖注入DI或者叫做控制反转IOC,只要在在配置中配置好需要注入的类,并且给其生成好对应的set方法,spring容器在给我们实例化该对象的时候,就能根据反射给起注入需要的对象。配置中有的只是一个完整类名字符串,而不是什么对象,如果没有反射,这些都是不可能做到的,也就说没有反射,就没有所谓的框架。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在向学生讲解Class.forName()方法的使用时,有时需要扩展讲解为什么这样书写的原理,于是,扩展讲解Java反射技术可以查看被监视类的方法(构造方法和普通方法)、公有属性的功能,以达到封闭功能的效果。该例子使用MyEclipse 5.5完成demo示例。其中,com.jb.arklis.app.DemoApplication类利用反射技术可以观察任何非静态类(比如java.lang.String, javax.swing.JFrame等类和自定义的类,比如com.jb.arklis.dao.BaseDAO)的普通方法、构造方法以公有属性,是一个非常有实用意义的显示类。 该示例没有使用泛型技术,所以不是很完美。不过只要你稍微修改一下,就可作为自己工程中比较好的封装工具类使用! 下载解压之后,使用MyEclipse 5.5导入,打开该工程,找到DemoApplication类,然后点击run菜单-->找到(x)Arguments,然后在Program arguments中输入: com.jb.arklis.dao.BaseDAO, 然后点击run按钮,如果一切正常,那么你会看到使用反射在DemoApplication类中呼叫了BaseDAO的returnTestValue(String name)方法。 我的代码注释非常详细,相信当你看完之后,一般来说,如果不是新手(非常菜的人),那么你应该学会使用反射技术来实现封装的动作了--也就是说,你的技术有了一个非常大的提高--如果你看完之后,参见该示例中另外的JDBC代码,然后能够实现对JDBC进一步的封装,使JDBC连接的使用步骤更简单的话! OK,Good luck!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值