------ android培训、java培训、期待与您交流! ----------
反射是Java中最重要的概念之一,它可以构成各个框架,能快速的搭建需要的类。所以,学Java就必须掌握好反射的应用。
Java程序中各个Java类属于同一类事物,描述这类事物的Java类名就是Class。Class类是反射的基石,只有通过Class类才能实现反射的功能。
获取Class对象的方式
//通过创建对象获取字节码对象
1,Person p = new Person();
Class cls1 = p.getClass();
//任意数据类型都具备一个class静态属性
2,Class cls2 = Person.class;
//按类名作为字符串传递给Class类中的static方法forName即可
3,Class cls3 = Class.forName("java.lang.Person");
需要注意的是:
int.class == Integer.TYPE
数组类型的Class不是基本数据类型,Class.isArray()
反射:就是把Java类中的各种成分映射成相应的Java类,然后对这些类进行操作。
如:Contructor,Field,Method,Package等
Constructor类:(构造函数类)
通过反射的方式来构造一个函数,实现方式代码:new String(new StringBuffer("abc"));
Constructor<String> constructor1 =
String.class.getConstructor(StringBuilder.class);
String str1 = constructor1.newInstance(new StringBuilder("abc"));
System.out.println(str1.charAt(2));
先用Class类调用getConstructor(参数.class)方法得到Constructor类,再用newInstance("参数")的方法来创建一个这个类的对象。
Class类的newInstance()方法是使用该类无参的构造函数创建对象, 如果一个类没有无参的构造函数, 就不能这样创建了
Field
Class.getField(String)方法可以获取类中的指定字段(可见的),如果是私有的可以用getDeclaedField("name")方法获取
如果是私有的需要先调用setAccessible(true)设置访问权限,用获取的指定的字段调用get(obj)可以获取指定对象中该字段的值
通过set(obj, newValue)方法可以设置指定对象上该字段的值
//这了是一个类,其中有两个变量 private x , public y
ReflectPoint pt1 = new ReflectPoint(3,5);
//得到public变量的方法
Field feildY = pt1.getClass().getField("y");
System.out.println(feildY.get(pt1));
//得到private变量的方法
Field feildX = pt1.getClass().getDeclaredField("x");
//必须强制设置可获取
feildX.setAccessible(true);
System.out.println(feildX.get(pt1));
Method
只需要知道方法的名称即可。 Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以获取类中的指定方法
调用invoke(Object, Object...)可以调用该方法
//得到String类中的charAt方法,反射调用之
Method charAt = String.class.getMethod("charAt", int.class);
System.out.println(charAt.invoke(str, 1));
如果传递给Method对象的invoke()方法的第一个参数为null,那么该Method对象对应的是一个静态方法
数组反射:
通过Array类中方法来完成。
将数组转化成一个Object类,传递进去。通过isArray()方法确定其是否为数组,用Array.get(obj,index)来调用。
private static void printObject(Object obj) {
if (obj.getClass().isArray()) {
int len = Array.getLength(obj);
for (int i = 0; i < len; i++) {
System.out.println(Array.get(obj, i));
}
}else {
System.out.println(obj);
}
内省
JavaBean是一种特殊的Java类,主要用于传递数据信息。这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则
JDK中提供了对JavaBean进行操作地API,这些API称为内省。
内省就是反射过程中,因为要设置、获取类中的成员变量时,而通过getField方法实现代码太过于复杂。仅仅是设置、获取两个操作就要写上很多代码,不利于工作,从而简化内容而出现了内省机制。
通过规定设置用setXXX方法,获取用getXXX方法来统一命名,这样就可以把getField中复杂的代码封装在内部,对外提供一些简单的方法即可实现设置、获取操作。
下面写出2种最简单的用反射获取到get和set方法的例子:
//通过使用PropertyDescriptor类,接收成员变量的名称,该类的Class对象
PropertyDescriptor pd1 = new PropertyDescriptor(propertyName,pt1.getClass());
//调用PropertyDescriptor类中的getWriteMethod()方法来得到设置方法
//调用getReadMethod()来得到获取方法
Method methodSetX = pd1.getWriteMethod();
methodSetX.invoke(pt1, setVal);
BreanUtils.jar包和Logging.jar包把这些方法也封装成对象,只要传入参数就可以直接用调用set、get方法,