Java内省机制小总结
Java中的反射机制是通过名称得到类的方法和对象的成份,对于一切Java类都是适用的,但是有时候使用起来比较麻烦。而JavaBean是一种特殊的Java类,遵守JavaBean的规范,即所有的成员都是私有成员,且每个成员都有公开的读取和设定的方法(getter和setter),且这些方法都遵守命名的规范。就是因为JavaBean有这些的特性,sun推出了一种专门对JavaBean成员进行访问的技术,方便对其的访问,就是内省技术。
首先,内省使用的几个类(接口)为java.beans.PropertyDescriptor,java.beans.Introspector和java.beans.beanInfo。其中的PropertyDescriptor是对一个Bean属性的描述,它提供了一系列对Bean属性进行操作的方法,Introspector是一个工具类,提供了一系列取得Bean信息的方法,beanInfo是对一个Bean的描述,可以通过它取得Bean内部的信息。
下面有几个小的DEMO
首先是定义一个Bean,见下面代码:
package com.heima.domain;
public class Student {
private String name;
private int age;
private Address address;
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", address="
+ address + "]";
}
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public Student(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
}
下面对Bean的一个属性进行赋值:
private void setValue() throws Exception {
Student student = new Student();
//得到对属性的描述
PropertyDescriptor descriptor = new PropertyDescriptor("name", Student.class);
//得到写方法
Method method = descriptor.getWriteMethod();
//使用反射调用方法,进行赋值
method.invoke(student, "狗蛋儿");
System.out.println(student);
}
再来一个对Bean所有属性进行赋值的例子:
private void copyProperties2(HttpServletRequest request) throws Exception {
Map<String, String[]> map = request.getParameterMap();
Student student = new Student();
//得到参数Map
for (Map.Entry<String, String[]> me : map.entrySet()) {
String name = me.getKey();
String[] values = me.getValue();
//分别得到每个每个属性的描述对象
PropertyDescriptor descriptor = new PropertyDescriptor(name, Student.class);
Method method = descriptor.getWriteMethod();
//这里因为Values可能是一个数组,不强转为一个对对象会出现异常
if (values.length > 1) {
method.invoke(student, (Object)values);
} else {
method.invoke(student, values);
}
}
}
我们可以看到使用内省机制对Bean属性进行操作还是很复杂的,那肯定有人来做工具帮助完成这一系列的操作,最后再来一个使用Map对Bean中的属性进行赋值的例子
private void copyProperties(HttpServletRequest request) {
Student student = new Student();
try {
BeanUtils.populate(student, request.getParameterMap());//使用BeanUtils的populate方法,将Map中的键值对赋值到Bean中
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
其中使用了BeanUtils的一些方法,BeanUtils带包名是org.apache.commons.beanutils.BeanUtils;是apache给出的,用来解决使用内省机制繁琐的问题。使用时要导入两个包:commons-beanutils-1.9.2.jar和commons-logging-1.1.1.jar。
使用内省机制要比反射简单一点,使用工具后这种差异更明显了,在Web的工作中可以多少使用,或者自己再包装一下,用着更顺手^^.