黑马程序员技术交流社区

标题: 浅谈反射 [打印本页]

作者: Aaron木头    时间: 2017-12-5 19:22
标题: 浅谈反射
Java的反射机制就是增加程序的灵活性,避免将程序写死到代码里。
    例如: 实例化一个 person()对象, 不使用反射, new person(); 如果想变成 实例化 其他类, 那么必须修改源代码,并重新编译。
    使用反射: class.forName("person").newInstance(); 而且这个类描述可以写到配置文件中,如 **.xml, 这样如果想实例化其他类,只要修改配置文件的"类描述"就可以了,不需要重新修改代码并编译。
    反射其实就是程序能够自检查自身信息。就像程序会照镜子反光看自己。在程序中可以检查某个类中的方法属性等信息,并且能够动态调用。这样可以写出很灵活的程序。
比如要把一个对象中的数据copy到另外一个对象中,规则是属性名相同就copy就可以用反射来做,不需要指定每个属性的名字,只要动态从类中取得信息,再判断属性名是否相同即可。当然应用还有很多。
    反射可以结合Java的字节码,使用ASM和cglib等库,还能动态生成类。hibernate的延迟载入,spring的AOP都是这么实现的。反射给Java带来了一些动态性。不过虽然很好,但毕竟还是有一定局限性的。另外ASM,cglib使用还是不放便。因此一些纯动态语言现在是一个重要发展趋势,比如ruby,python等,程序很容易动态生成。增加程序的灵活性。

    如struts中。请求的派发控制。
当请求来到时。struts通过查询配置文件。找到该请求对应的action。已经方法。然后通过反射实例化action。并调用响应method。如果不适用反射,那么你就只能写死到代码里了。所以说,一个灵活,一个不灵活。
    很少情况下是非用反射不可的。大多数情况下反射是为了提高程序的灵活性。因此一般框架中使用较多。因为框架要适用更多的情况。对灵活性要求较高。
    代码案例:public class Test {
                        public static void main(String[] args) throws Exception{
                                //获取Student类字节码对象
                                Class clazz = Class.forName("com.itheima.my4.Student");
                                
                                //创建对象
                                Object stu = clazz.newInstance();
                                
                                //获取公共的成员方法并执行
                                Method m1 = clazz.getMethod("publicShow");
                                //执行方法
                                m1.invoke(stu);
                                
                                //获取私有的成员方法并执行
                                Method m2 = clazz.getDeclaredMethod("privateShow");
                                //去除私有权限
                                m2.setAccessible(true);
                                //执行方法
                                m2.invoke(stu);
                                
                                //获取公共的有参有返回值的方法
                                Method m3 = clazz.getMethod("getSum", int.class,int.class);
                                //执行方法。获取返回值
                                Object sum = m3.invoke(stu, 5,5);
                                System.out.println(sum);
                                
                                //获取私有的有参有返回值的方法
                                Method m4 = clazz.getDeclaredMethod("getStr", String.class,String.class);
                                //去除私有权限
                                m4.setAccessible(true);
                                //执行方法,获取返回值
                                Object newStr = m4.invoke(stu, "abc","def");
                                System.out.println(newStr);
                        }
                }





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2