一、Javabean
1.JavaBean是一種特殊的Java類,主要用於傳遞資料資訊,這種java類中的方法主要用於訪問私人的欄位,且方法名符合某種命名規則。
如果要在兩個模組之間傳遞多個資訊,可以將這些資訊封裝到一個JavaBean中,這種JavaBean的執行個體對象通常稱之為值對象(Value Object,簡稱VO)。這些資訊在類中用私人欄位來儲存,如果讀取或設定這些欄位的值,則需要通過一些相應的方法來訪問,大家覺得這些方法的名稱叫什麼好呢?JavaBean的屬性是根據其中的setter和getter方法來確定的,而不是根據其中的成員變數。如果方法名為setId,中文意思即為設定id,至於你把它存到哪個變數上,用管嗎?如果方法名為getId,中文意思即為擷取id,至於你從哪個變數上取,用管嗎?去掉set首碼,剩餘部分就是屬性名稱,如果剩餘部分的第二個字母是小寫,則把剩餘部分的首字母改成小的。
- setId()的屬性名稱---->id
- isLast()的屬性名稱---->last
- setCPU的屬性名稱是什麼?---->CPU
- getUPS的屬性名稱是什嗎?---->UPS
總之,一個類被當作javaBean使用時,JavaBean的屬性是根據方法名推斷出來的,它根本看不到java類內部的成員變數。
2.一個符合JavaBean特點的類可以當作普通類一樣進行使用,但把它當JavaBean用肯定需要帶來一些額外的好處,我們才會去瞭解和應用JavaBean!好處如下:
- 在Java EE開發中,經常要使用到JavaBean。很多環境就要求按JavaBean方式進行操作,別人都這麼用和要求這麼做,那你就沒什麼挑選的餘地!
- JDK中提供了對JavaBean進行操作的一些API,這套API就稱為內省。如果要你自己去通過getX方法來訪問私人的x,怎麼做,有一定難度吧?用內省這套api操作JavaBean比用普通類的方式更方便。
二、PropertyDescriptor BeanInfo BeanUtils PropertyUtils操作javabean 見代碼所示:
import java.util.Date;public class Person{ private String name; private int age; private Date birthday=new Date();//這裡要建立對象! public Date getBirthday(){return birthday;}public void setBirthday(Date birthday){this.birthday = birthday;}public Person(String name, int age){super();this.name = name;this.age = 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;}@Overridepublic String toString(){return this.name+" "+this.age+" "+this.birthday;} }
import java.beans.BeanInfo;import java.beans.IntrospectionException;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import org.apache.commons.beanutils.BeanUtils;import org.apache.commons.beanutils.PropertyUtils;public class IntrospectorTest{/** * 各種類操作javabean */public static void main(String[] args)throws Exception{Person p=new Person("張三",23);String propertyName="name";//1.以下使用PropertyDescriptor操作javabeangetProperty(p, propertyName);Object val="張凱";setProperty(p, propertyName, val);//2.以下使用BeanInfo操作javabeangetPropertyByBeanInfo(p, propertyName);//3.以下使用BeanUtils操作javabean。BeanUtils.setProperty(p, propertyName,"李四" );//這是屬性鏈,birthday是Date類型的,Date中有setTime(long time)方法BeanUtils.setProperty(p, "birthday.time","11111");System.out.println(BeanUtils.getProperty(p, "birthday.time"));//BeanUtils操作中參數是String類型的 返回結果也是String類型System.out.println(BeanUtils.getProperty(p, "birthday.time").getClass().getName());//4.PropertyUtils操作javabeanPropertyUtils.setProperty(p, "name", "lily");PropertyUtils.setProperty(p, "age", 30);//傳入是是intSystem.out.println(PropertyUtils.getProperty(p, "age").getClass().getName());//返回是IntegerPropertyUtils.setProperty(p, "birthday.time", 10000);System.out.println(p);}public static void getPropertyByBeanInfo(Person p, String propertyName)throws IntrospectionException, IllegalAccessException,InvocationTargetException{BeanInfo beanInfo=Introspector.getBeanInfo(p.getClass());PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();//遍曆數組找到指定屬性for(PropertyDescriptor pd:pds){if(pd.getName().equals(propertyName)){ System.out.println(pd.getReadMethod().invoke(p));break;}}} //設定屬性方法public static void setProperty(Person p, String propertyName, Object val)throws IntrospectionException, IllegalAccessException,InvocationTargetException{PropertyDescriptor pd1=new PropertyDescriptor(propertyName,p.getClass());Method methodSet=pd1.getWriteMethod();methodSet.invoke(p, val);//調用set方法把name值設定為“張凱”System.out.println(p);}//得到屬性方法private static void getProperty(Person p, String propertyName)throws IntrospectionException, IllegalAccessException,InvocationTargetException{ //擷取javaBean的屬性描述PropertyDescriptor pd=new PropertyDescriptor(propertyName,p.getClass());//得到方法Method methodGet=pd.getReadMethod();System.out.println(methodGet.invoke(p));//調用方法}}
三、其他用struts的迭代標籤不能迭代出枚舉元素的屬性,而用jstl的迭代標籤則可以。採用BeanUtils去擷取帶有抽象方法的枚舉類的成員對象的屬性時,會出現錯誤,要自己用內省加暴力反射方式才可以擷取。主要原因是枚舉類的抽象子類不是public類型的。
public static void main(String[] args) {// TODO Auto-generated method stub/*System.out.println(PropertyUtils.getProperty(Sex.NONE, "title"));*/Object bean = Sex.NONE;BeanInfo beanInfo = null;try {beanInfo = Introspector.getBeanInfo(bean.getClass());} catch (Exception e1) {// TODO Auto-generated catch blocke1.printStackTrace();}PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors();for(PropertyDescriptor property:properties){if(property.getName().equals("title")){Method method = property.getReadMethod();method.setAccessible(true);Object retVal;try {retVal = method.invoke(bean, null); System.out.println(retVal);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}