内省访问JavaBean属性的两种方式:
1、通过PropertyDescriptor类操作Bean的属性
2、通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法。
案例如下:首先创建一个普通的Java类Student类,该类位于cn.csdn.reflect包中并编译产生相应的class文件.:
public class StudentTest {
@Test
public void test() throws IntrospectionException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
Student st = new Student();
// 1、通过Introspector类获得Bean对象的 BeanInfo,
BeanInfo entity = Introspector.getBeanInfo(Student.class);
// 2、然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor )
PropertyDescriptor pdrs[] = entity.getPropertyDescriptors();
// 3、通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,
for (PropertyDescriptor pd : pdrs) {
// System.out.println(pd.getName());
/*
* System.out.println(pd.getShortDescription());
* System.out.println(pd.getDisplayName());
*/
/* if (pd.getName().equals("age")) {
Method md = pd.getWriteMethod();
md.invoke(st, 12);
}*/
//获取属性的类型
System.out.println(pd.getName()+" "+pd.getPropertyType());
}
// System.out.println(st.getAge());
}
以上那种方法不常用 只做了解就行,下面讲述的方法比较简单,常用
//简便的方法
@Test
public void test1()throws Exception{
Student st = new Student();
//通过构造器 创建 PropertyDescriptor对象
PropertyDescriptor pd = new PropertyDescriptor("age", Student.class);
Method md = pd.getWriteMethod(); //写操作
md.invoke(st, 120);
System.out.println(st.getAge());
//
md = pd.getReadMethod();
int value = (Integer)md.invoke(st, null); //读操作
System.out.println(value);
}
}
但是Sun公司的内省API过于繁琐,所以Apache组织结合很多实际开发中的应用场景开发了一套简单、易用的API操作Bean的属性——BeanUtiles
Beanutils工具包的常用类:
BeanUtiles、PropertyUtiles、ConvertUtils.regsiter(Converter convert, Class class)、自定义转换public class Demo01 {
/* 采用BeanUtils为Student 的name属性赋值 */
@Test
public void test1() throws Exception {
// 1、加载Class文件
Class cls = Class.forName("cn.csdn.beanutils.Student");
// 2、创建bean对象
Student bean = (Student) cls.newInstance();
// 3、采用BeanUtils对name属性赋值
BeanUtils.setProperty(bean, "name", "xxx");
//
String value = BeanUtils.getProperty(bean, "name");
System.out.println(value);
}
/* Beanutils支持基本数据类型的自动转换 */
@Test
public void test2() throws Exception {
// 1、定义class文件
String className = "cn.csdn.beanutils.Student";
// 2、定义操作的属性
String name = "age";
// 3、创建class对象
Class cls = Class.forName(className);
// 4、创建bean对象
Student bean = (Student) cls.newInstance();
// 5、为操作的bean对象的name属性赋值
BeanUtils.setProperty(bean, name, "200");
// 6、执行输出
System.out.println(bean.getAge());
}
@Test
public void test3() throws IllegalAccessException,
InvocationTargetException {
Student st = new Student();
BeanUtils.setProperty(st, "name", "redarmy"); // 避免了基本的数据类型转换的问题
System.out.println(st.getName());
}
@Test
public void test4() throws Exception {
Student bean = new Student();
BeanUtils.setProperty(bean, "birthday", new Date());
System.out.println(bean.getBirthday());
}
@Test
public void test5() throws Exception {
Student bean = new Student();
// 自带的转换器
ConvertUtils.register(new DateLocaleConverter(), Date.class);
BeanUtils.setProperty(bean, "birthday", "1997-12-12");
System.out.println(bean.getBirthday());
}
@Test
public void test6() throws Exception {
Student bean = new Student();
//自定义转换器
ConvertUtils.register(new Converter() {
// 转换的类型 //转换的值
public Object convert(Class type, Object value) {
if (value == null) {
return null;
}
SimpleDateFormat sdi = new SimpleDateFormat("yyyy-MM-dd");
//注意MM必须用大写
Date dt = null;
try {
dt = sdi.parse((String) value);
} catch (ParseException e) {
throw new ConversionException("日期格式转换有问题....");
}
return dt;
}
}, Date.class);
BeanUtils.setProperty(bean, "birthday", "1997-11-12");
System.out.println(bean.getBirthday()); //toString();
}
}
注意:接口不能new 一个对象,Converter就是一个接口,如果必须要new 一个新的对象的话,必须重写接口中 的方法,相当于 相当于 public class MyConverter implements Converter{ } 并且 创建了MyConveter的对象 new MyConverter()的匿名的对象