首页 > 编程语言 > 详细

浅说Java中的反射机制(二)

时间:2016-03-28 16:52:17      阅读:161      评论:0      收藏:0      [点我收藏+]

   写过一篇Java中的反射机制,不算是写,应该是抄了,因为那是别人写的,这一篇也是别人写的,摘抄如下:

   引自于Java基础--反射机制的知识点梳理,作者醉眼识朦胧。(()为我手记)

   什么是反射?

   正常编译执行java文件时,会生成一个.class文件,反射就是一个反编译的过程,它可以通过.class文件得到一个java对象。一个类会有很多组成部分,比如成员变量、成员方法、构造方法等,反射可以通过加载类(加载类是个什么东西?一直搞不清楚),解剖出类的各个组成部分。

   为什么要用反射?

   我们需要访问一个类的方法或字段的时候,直接new一个该类的对象然后调用就好了,干嘛要用反射呢?刚学的时候我也不懂,并且学了也没机会用到,或者根本用不到,后来开始接触strut2、hibernate等一些框架的时候,才慢慢懂得了一点反射的强大之处。在框架中会有很多配置文件,而配置文件中一般只有一些类的全路径的字符串,而就是通过这些个字符串,就能得到这个类的对象,以及类中所有的信息。我给你这个类,当然你可以轻松得到它的实例,但如果我给你的只是这个类的路径的字符串呢?没有反射你就傻眼了吧。学习反射一般只会在写框架的时候用到,如果你没有达到写框架的高度,能够看懂别人的框架也是极好的。

   这里面还涉及到一个静态编译和动态编译(静态编译和动态编译应该是过的,但是忘记了)的概念,前者的意思就是在编译的时候已经绑定了对象,确定了对象;而动态编译就是直到运行的时候,才根据需要去绑定对象。

   加载类:

   加载类就是获得类的字节码。要想通过反射获取到一个类的内部信息,首先得先获取到这个类的字节码对象。

   加载类有三种方式:

   现在我有一个类User,我希望加载这个类,获得它的字节码对象:

package cn.ren.reflect2;

public class Demo {

    public static void main(String[] args) throws ClassNotFoundException {
        //第一种方式, 通过Class的forName方法,注意使用目标类的全路径
        Class clazz = Class.forName("cn.ren.reflect2.User");
        
        //第二种方式,通过Object类的getClass()方法
        Class clazz1 = new User().getClass();
        
        //第三种方式,通过类的.class属性
        Class clazz2 = User.class;
    }

}

   一般第一种方式最常用,也最好用,因为看代码我们可以发现,后两种在编译前就必须要知道具体的类的,否则就无法通过编译,而第一种方式,没有那么大的强制性,他只是提供了一个空间,运行时你可以想把谁传给它就把谁传给它,这个类甚至可以不存在,后果只是抛出一个异常。

   反射类的方法(Method):

   一个类中总会有实现某些功能的方法,这些方法可能有返回值也可能没有返回值,可能有参数也可能没参数,可能是静态方法也可能是普通方法。下面通过例子分别讲解:

package cn.ren.reflect2;

import java.lang.reflect.Method;

public class Test {

    public static void main(String[] args) throws Exception {
        User u = new User();
        //通过Class的forName方法,注意使用目标类的全路径
        Class clazz = Class.forName("cn.ren.reflect2.User");
        
        /*
         * 获取无参无返回值的方法login
         * 获得一个方法名为"login"但是没有参数的Method对象
         */
        Method method = clazz.getMethod("login", null);
        
        /*
         * 第一个参数:要想执行这个login方法你总得告诉她是哪个User的login方法吧
         * 第二个参数就是login方法的参数(实参),这里为null
         */
        method.invoke(u, null);
        
        //获取有参有返回值的方法eat
        Method method1 = clazz.getMethod("eat", String.class);
        String agrs = (String) method1.invoke(u, "超人");
        
        /*
         * 获取带参无返回值的静态方法sleep
         * 静态方法,可以不提供User对象,传一个null即可
         */
        Method method2 = clazz.getMethod("sleep", String.class);
        method2.invoke(null, "蝙蝠侠");
     }
}

   打印结果为:

无参构造函数
用户登录了
超人去吃饭了
蝙蝠侠去睡觉了

   反射类的字段:

   

 

浅说Java中的反射机制(二)

原文:http://www.cnblogs.com/yerenyuan/p/5329448.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!