内省Introspector
内省是用来操作javabean属性的,其实就是特殊的反射
什么是javabean? 以及javabean的属性?
比如一个学生,现在要用一个对象去封装学生的数据,封装某一个实体数据的java对象就叫做一个javabean
public class Student {
private String name; //开始是字段,不是属性,拥有了get,set方法后才能称之为属性
private int age;
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 String getXx(){ //
return "aa";
}
}
一个javabean有什么属性是由get,set方法决定的,该javabean一共有四个属性
name , age , xx , class 任何类都是object object有getClass方法,所以还有一个classs属性
内省访问JavaBean属性的两种方式:
1,通过PropertyDescriptor类操作Bean的属性
2,通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法。
@Test
public void test1() throws Exception, {
Student bean = new Student();
//得到bean的所有属性
BeanInfo info = Introspector.getBeanInfo(Student.class);
//得到bean的所有属性描述器
PropertyDescriptor pds[] = info.getPropertyDescriptors();
//迭代 出bean的所有属性找出 name属性并赋值
for(PropertyDescriptor pd : pds){ //name
String propertyName = pd.getName();
if(propertyName.equals("name")){
Method m = pd.getWriteMethod(); //setName(String name)
m.invoke(bean, "关羽");
}
}
System.out.println(bean.getName());
}
//操作bean的指定属性: age
@Test
public void test2() throws Exception {
Student bean = new Student();
PropertyDescriptor pd = new PropertyDescriptor("age",bean.getClass());
//通过内省设置bean的age属性
Method method = pd.getWriteMethod(); //setAge(int age)
method.invoke(bean, 12);
//通过内省获取bean的age属性
method = pd.getReadMethod(); // getAge()
int age = (Integer) method.invoke(bean, null);
System.out.println(age);
}
内省—beanutils工具包
一套简单、易用的API操作Bean的属性
//基本操作:设置、读取name属性
@Test
public void test1() throws Exception{
Student bean = new Student();
BeanUtils.setProperty(bean, "name", "张飞");
String name = BeanUtils.getProperty(bean, "name");
System.out.println(name);
}
//较高级的操作: 设置int 类型的age属性
@Test
public void test2() throws Exception{
Student bean = new Student();
BeanUtils.setProperty(bean, "age", "12"); //beanutils框架会自动对数据进行转换,这仅于8种基本数据类型
System.out.println(bean.getAge()+1);
}
//高级的操作:设置date 类型的 birthday 属性
@Test
public void test3() throws Exception{
Student bean = new Student();
//注册日期转换器
ConvertUtils.register(new Converter(){
public Object convert(Class type, Object value) {
if(value==null){
return null;
}
if(!(value instanceof String)){
throw new ConversionException("只支持字符串的转换");
}
String date = (String) value;
if(date.trim().equals("")){
return null;
}
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try {
return df.parse(date);
} catch (ParseException e) {
throw new ConversionException(e);
}
}
}, Date.class);
BeanUtils.setProperty(bean, "birthday", ""); //beanutils框架会自动对数据进行转换
System.out.println(bean.getBirthday()); //date.toString()
}
//高级的操作: 使用beanutils框架内置的转换器
//老方说此转换器在开发过程中一般不使用,因为不完美,如果客户机传入一个空字符串户抛ConversionException ,导致后面的程序很难写,所以一般都要自己写转换器
@Test
public void test4() throws Exception{
Student bean = new Student();
//使用转换Date类型的转换器
ConvertUtils.register(new DateLocaleConverter(), Date.class);
BeanUtils.setProperty(bean, "birthday", ""); //beanutils框架会自动对数据进行转换
System.out.println(bean.getBirthday()); //date.toString()
}