内省是什么?
开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都是用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作Java对象的属性。
什么是Java对象的属性和属性的读写方法?
内省访问JavaBean属性的两种方式:
1.通过ProperityDescriptor类操作Bean的属性;
2.通过Introspector类获得Bean对象的BeanInfo,然后通过BeanInfo来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获得某个属性对应的getter/setter方法,然后通过反射机制来调用这些方法。
在类中声明成员变量(private String name;)只能是叫做成员变量或者叫做字段,只有当声明了该字段的set和get方法时才能成这个成员变量为属性。
下面看使用jdkapi中的内省调用类里面的属性。
1 package cn.itcast.instrospector; 2 3 import java.beans.BeanInfo; 4 import java.beans.IntrospectionException; 5 import java.beans.Introspector; 6 import java.beans.PropertyDescriptor; 7 import java.lang.reflect.Method; 8 9 import org.junit.Test; 10 11 public class Demo1 { 12 13 //通过内省api操作bean的name属性 14 @Test 15 public void test1() throws Exception{ 16 Student s = new Student(); 17 18 PropertyDescriptor pd = new PropertyDescriptor("name",Student.class); 19 Method method = pd.getWriteMethod(); 20 method.invoke(s, "flx"); 21 //System.out.println(s.getName()); 22 method = pd.getReadMethod(); 23 String result = (String) method.invoke(s, null); 24 System.out.println(result); 25 } 26 27 //操作bean的所有属性 28 @Test 29 public void test2() throws Exception{ 30 BeanInfo info = Introspector.getBeanInfo(Student.class); 31 PropertyDescriptor pds[] = info.getPropertyDescriptors(); 32 for(PropertyDescriptor pd:pds){ 33 System.out.println(pd.getName()); 34 } 35 } 36 }
1 package cn.itcast.instrospector; 2 3 public class Student { 4 private String name; 5 6 public String getName() { 7 return name; 8 } 9 10 public void setName(String name) { 11 this.name = name; 12 } 13 }
下面看使用BeanUtils操作属性
1 package cn.itcast.beanutils; 2 3 import java.lang.reflect.InvocationTargetException; 4 import java.util.Date; 5 6 import org.apache.commons.beanutils.BeanUtils; 7 import org.apache.commons.beanutils.ConvertUtils; 8 import org.apache.commons.beanutils.converters.DateConverter; 9 import org.apache.commons.beanutils.locale.converters.DateLocaleConverter; 10 11 public class Demo1 { 12 public static void main(String [] args) throws IllegalAccessException, InvocationTargetException{ 13 String name = "fix"; 14 String password = "123"; 15 String age = "23"; 16 String email = "flx@sina.com"; 17 String birthday = "1990-09-09"; 18 19 Student s = new Student(); 20 21 ConvertUtils.register(new DateLocaleConverter(), Date.class); 22 BeanUtils.setProperty(s, "name", name); 23 BeanUtils.setProperty(s, "password", password); 24 BeanUtils.setProperty(s, "age", age); 25 BeanUtils.setProperty(s, "email", email); 26 BeanUtils.setProperty(s, "birthday", birthday); 27 System.out.println(s.getEmail()); 28 System.out.println(s.getBirthday()); 29 } 30 31 }
这里第21行注册了一个转化器,使日期可以转换成当地日期。下面是Student类
1 package cn.itcast.beanutils; 2 3 import java.util.Date; 4 5 public class Student { 6 private String name; 7 private String password; 8 private String email; 9 private int age; 10 private Date birthday; 11 public String getPassword() { 12 return password; 13 } 14 15 public void setPassword(String password) { 16 this.password = password; 17 } 18 19 public String getEmail() { 20 return email; 21 } 22 23 public void setEmail(String email) { 24 this.email = email; 25 } 26 27 public int getAge() { 28 return age; 29 } 30 31 public void setAge(int age) { 32 this.age = age; 33 } 34 35 public Date getBirthday() { 36 return birthday; 37 } 38 39 public void setBirthday(Date birthday) { 40 this.birthday = birthday; 41 } 42 43 public String getName() { 44 return name; 45 } 46 47 public void setName(String name) { 48 this.name = name; 49 } 50 }
但是,如果我们输入的数据类型没有对应的转化器,我们就要自己写一个转换器。
下面看如何写一个转换器。
1 package cn.itcast.beanutils; 2 3 import java.lang.reflect.InvocationTargetException; 4 import java.text.ParseException; 5 import java.text.SimpleDateFormat; 6 import java.util.Date; 7 8 import org.apache.commons.beanutils.BeanUtils; 9 import org.apache.commons.beanutils.ConversionException; 10 import org.apache.commons.beanutils.ConvertUtils; 11 import org.apache.commons.beanutils.Converter; 12 import org.apache.commons.beanutils.converters.DateConverter; 13 import org.apache.commons.beanutils.locale.converters.DateLocaleConverter; 14 15 public class Demo1 { 16 public static void main(String [] args) throws IllegalAccessException, InvocationTargetException{ 17 String name = "fix"; 18 String password = "123"; 19 String age = "23"; 20 String email = "flx@sina.com"; 21 String birthday = "1990-09-09"; 22 23 Student s = new Student(); 24 25 //自己设计转换器 26 ConvertUtils.register(new Converter(){ 27 public Object convert(Class type,Object value){//"1980-09-09" 28 if(value==null){ 29 return null; 30 } 31 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 32 Date date = null; 33 try { 34 date = format.parse((String) value); 35 } catch (ParseException e) { 36 // TODO Auto-generated catch block 37 e.printStackTrace(); 38 throw new ConversionException(e); 39 } 40 return date; 41 } 42 }, Date.class); 43 BeanUtils.setProperty(s, "name", name); 44 BeanUtils.setProperty(s, "password", password); 45 BeanUtils.setProperty(s, "age", age); 46 BeanUtils.setProperty(s, "email", email); 47 BeanUtils.setProperty(s, "birthday", birthday); 48 System.out.println(s.getEmail()); 49 System.out.println(s.getBirthday()); 50 } 51 52 }
以上就是内省的一些使用技巧,这里在能用到BeanUtils是尽量用BeanUtils。