Java 反射,
Java 反射,
网上讲反射的很多,不知道为什么我总是觉得找的资料都不是我想要的那种,很多人都说的不够全面。我这里也不打算说全面,但是就谈谈常用的几个用法吧。
一般讲反射首先就是要获取到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) 对成员变量进行赋值取值操作。
具体也就这么多内容了。
相关文章
- 暂无相关文章
用户点评