Java 反射

来源:互联网 发布:淘宝服务态度评分降低 编辑:程序博客网 时间:2024/06/05 17:32

网上讲反射的很多,不知道为什么我总是觉得找的资料都不是我想要的那种,很多人都说的不够全面。我这里也不打算说全面,但是就谈谈常用的几个用法吧。

一般讲反射首先就是要获取到Class对象,这个据说有三四种方法,但最常用的是:

Class cls = Class.forName("类在项目中的相对路径");//com.xyjj.Person

这样就获取到这个类的类对象,

学习反射其实就是为了获取这个类中的一些东西 比如 构造函数,成员变量,成员方法;这也是学习的目的,所以你应该往这几个方面去考虑问题,否则没必要学。

那么接下来你会去查API文档,发现里面大部分方法都是 getCon..  getMethod   getField 与 getDeclaredCon...   getDeclaredxxx   ...

这里我搜了一些资料,也包括自己手动去测试

public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
        throws NoSuchMethodException, SecurityException {
        // be very careful not to change the stack depth of this
        // checkMemberAccess call for security reasons
        // see java.lang.SecurityManager.checkMemberAccess
        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
        Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
        if (method == null) {
            throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
        }
        return method;
    }

这是 getDeclaredMethod的源码 

发现 它先去查看成员的权限 里面参数Member.DECLARED是控制权限的 接着我们跳转到Member的源码

public
interface Member {


    /**
     * Identifies the set of all public members of a class or interface,
     * including inherited members.
     * @see java.lang.SecurityManager#checkMemberAccess
     */
    public static final int PUBLIC = 0;


    /**
     * Identifies the set of declared members of a class or interface.
     * Inherited members are not included.
     * @see java.lang.SecurityManager#checkMemberAccess
     */
    public static final int DECLARED = 1;

}

发现他是一个借口 里面固定了两个参数;

设置权限之后 searchMethods(privateGetDeclaredMethods(false), name, parameterTypes); 去寻找方法了 

然后将找到的方法返回出来 否则报错 至于怎么查找有兴趣自己去看好吧,同样的道理可以看到getMethod()源码

它的处理方法就和这个不一样,它会找到这个类以及父类的所有public方法 

了解了这个之后我们就知道在调用public 的属性与 private的属性的区别


我们在获取Class对象之后 如果还要获取Method 对象

Method method = cls.getDeclaredMethod("方法名",参数类); 这里参数类 如果是int 就写int.class 如果是其它对象 则new xxx.getClass();或是其它的获取类对象方法。

获取到method对象之后如果我要调用当前的这个method方法

method.invoke(Object object,参数);前面这个object 是一个类对象 就是你之前获取到的 cls  当然你这里需要将这个类初始化一下 除非它是静态类,这个你如果不理解我觉得你有必要回顾一下java基础的static属性 好吧 

method.invoke(cls.newInstance(),xxx) 这里参数你根据需求填好吧 然后就会执行类中的这个方法

若是静态方法  method.invoke(cls,xxx) 这样就好了。

当然这是在public修饰的方法里才能正确执行,若是private会报以下错误:

Class xy.reflect.Test can not access a member of class xy.reflect.ReflectTest with modifiers "private"


所以在获取method对象之后请加上 method.setAccessible(true); 


同理 获取构造函数时用到的是 

Constructor<?> con = cls.getDeclaredConstructor(Class<?> );   Class<?> == int.class,String.class,xxx.class....// 这里指参数所属类的Class对象。

获取到之后

通过 con.newInstance(具体参数); 编译器会自动帮你找到构造函数,

这里也可以执行private的构造函数,也是要加setAccessible(true) 但目前我没接触到这样的构造函数存在,在某些场合可能会有特殊的用途吧 ,一般是用public 来给其他类提供数据接口。


成员变量就是Field 了

Field  getDeclearField(成员变量名);

接着通过 set(Object obj,参数)    get(Object obj) 对成员变量进行赋值取值操作。

具体也就这么多内容了。

0 0
原创粉丝点击