|
Rentention、Target、注解的基本屬性和高級屬性 內(nèi)省IntroSpector JavaBean主要用于傳遞數(shù)據(jù)信息,其方法用于訪問私有變量,且方法名符合某種規(guī)則。 如果在兩個(gè)模塊之間傳遞信息,可以將信息封裝進(jìn)JavaBean中,這種對象稱為“值對象”(Value Object),或“VO”。方法比較少。這些信息儲存在類的私有變量中,通過set()、get()獲得。 內(nèi)省主要是對JavaBean進(jìn)行操作。JavaBean內(nèi)部的方法要按照某種規(guī)則命名,例如void setAge(int age)、int getAge()。JavaBean可以作為普通類進(jìn)行操作;普通類如果內(nèi)部有set()、get()方法,也可以當(dāng)做JavaBean使用。 JavaBean的屬性是通過get()和set()方法推斷出來的,即去掉get、set后的字母,例如,屬性為age,而不是成員變量,因?yàn)槌蓡T變量看不見。 獲得屬性名的規(guī)則:如果屬性名的第二個(gè)字母是小寫,則把第一個(gè)字母小寫。例如,gettime—>time,setTime—>time,getCPU—>CPU。 JavaBean處理的好處: 1、JavaEE中許多地方需要使用JavaBean。 2、JDK給JavaBean提供的API稱為內(nèi)省。 PropertyDescriptor類 PropertyDescriptor類表示JavaBean類通過存儲器導(dǎo)出一個(gè)屬性。主要方法: 1、getPropertyType(),獲得屬性的Class對象。 2、getReadMethod(),獲得用于讀取屬性值的方法;getWriteMethod(),獲得用于寫入屬性值的方法。 3、hashCode(),獲取對象的哈希值。 4、setReadMethod(Method readMethod),設(shè)置用于讀取屬性值的方法;setWriteMethod(MethodwriteMethod),設(shè)置用于寫入屬性值的方法; 導(dǎo)包java.bean.*; 通過屬性名獲取對應(yīng)的值,利用反射方法,如下: ReflectPoint pt1 = new ReflectPoint(7,9); String propertyName = "x";//給一個(gè)屬性,獲取值 PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass()); Method methodGetX = pd.getReadMethod();//Read對應(yīng)get()方法 Object reValue = methodGetX.invoke(pt1); 給某個(gè)屬性設(shè)置值,如下: String propertyName2 = "y";//給一個(gè)屬性,設(shè)置值 PropertyDescriptor pd2 = new PropertyDescriptor(propertyName2,pt1.getClass()); Method methodSetY = pd2.getWriteMethod();//Write對應(yīng)set()方法 methodSetY.invoke(pt1,3); 右鍵—》Source—》Generate Geters and Setters,創(chuàng)建get()和set()方法。 選擇一些代碼,右鍵—》Refactor—》Extract Method,創(chuàng)建一個(gè)方法,提高復(fù)用性。 Introspector類 將JavaBean中的屬性封裝起來進(jìn)行操作。在程序把一個(gè)類當(dāng)做JavaBean來看,就是調(diào)用Introspector.getBeanInfo()方法,得到的BeanInfo對象封裝了把這個(gè)類當(dāng)做JavaBean看的結(jié)果信息,即屬性的信息。需要導(dǎo)包java.beans.*。 getPropertyDescriptors(),獲得屬性的描述,可以采用遍歷BeanInfo的方法,來查找、設(shè)置類的屬性。 private static Object getProperty_2(Object pt1, String propertyName) throws Exception { BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass()); PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); Object reValue = null; for(PropertyDescriptor pd : pds) { if(pd.getName().equals(propertyName)) { Method methodGetX = pd.getReadMethod(); reValue = methodGetX.invoke(pt1); break; } } return reValue; } 通過這兩個(gè)類的比較可以看出,都是需要獲得PropertyDescriptor,只是方式不一樣:前者通過創(chuàng)建對象直接獲得,后者需要遍歷,所以使用PropertyDescriptor類更加方便。 BeanUtils工具包 為JavaBean提供更多、放方便的功能。 beanutils.jar = beanutils-core.jar + beanutils-bean-collections.jar,可以通過BuildPath,添加額外的jar包,或者工程下建立lib目錄,將jar包復(fù)制進(jìn)來,再加載這個(gè)jar包:右鍵—》add to BuildPath。使用時(shí)需要導(dǎo)包:org.apache.commons.beanutils.BeanUtils。 需要配合使用acpche提供的日志包:logging。 獲得屬性的值,例如,BeanUtils.getProperty(pt1,"x"),返回字符串 設(shè)置屬性的值,例如,BeanUtils.setProperty(pt1,"y",22),參數(shù)是字符串或基本類型自動包裝。設(shè)置屬性的值是字符串,獲得的值也是字符串,不是基本類型。 BeanUtils的特點(diǎn): 1、對基本數(shù)據(jù)類型的屬性的操作:在WEB開發(fā)、使用中,錄入和顯示時(shí),值會被轉(zhuǎn)換成字符串,但底層運(yùn)算用的是基本類型,這些類型轉(zhuǎn)到動作由BeanUtils自動完成。 2、對引用數(shù)據(jù)類型的屬性的操作:首先在類中必須有對象,不能是null,例如,private Date birthday=new Date();。操作的是對象的屬性而不是整個(gè)對象,例如,BeanUtils.setProperty(pt1,"birthday.time",121); Java7的新特性:Map和JavaBean之間可以進(jìn)行相互轉(zhuǎn)換,key是屬性,value是值。 describe:JavaBean—>Map;populate:Map—>JavaBean。例如: Map map = (name:Kim,age:18); BeanUtils.setProperty(map,"name","Kim"); copyProperties(Object dest, Objectorig),將一個(gè)對象的屬性值復(fù)制到另一個(gè)對象的屬性,需要保證屬性一致。 PropertyUtils類 和BeanUtils不同在于,運(yùn)行g(shù)etProperty、setProperty操作時(shí),沒有類型轉(zhuǎn)換,使用屬性的原有類型或者包裝類。 注解Annotation JDK1.5出現(xiàn)的新特性。在java.lang.annotation包中。 對于過時(shí)的語句,java會提示過時(shí)了,通過@SuppressWarnings("Deprecation")在DOS中取消提示,但Eclipse無法取消。這就是注解,相當(dāng)于標(biāo)記。編譯器、開發(fā)工具、javac通過反射獲得注解里的內(nèi)容,進(jìn)而明確應(yīng)該做什么、不應(yīng)該做什么。注解可以加在包、類、屬性、方法、參數(shù)及局部變量之上。 一個(gè)注解就是一個(gè)類。@SuppressWarnings,取消警告。@Deprecated,已過時(shí),老版可以用,新版無法用。 HashSet集合中,對象必須覆蓋Object類的equals()方法,否則會繼續(xù)使用Object類的equals()方法進(jìn)行比較,錯誤的比較方法。覆蓋equals()方法,參數(shù)必須一致,為了防止錯誤寫入本類的對象,加入@Override,必須正確覆蓋父類方法,不是創(chuàng)建新方法。 注解的應(yīng)用 在源程序中,調(diào)用一個(gè)類,這個(gè)類會用到注解,需要先準(zhǔn)備好注解類,類在調(diào)用注解類的對象。注解類的寫法類似接口,@interface。先寫好注解類A,將注解放在類B中,類C在調(diào)用類B時(shí)通過反射獲得注解類A的內(nèi)容,進(jìn)而明確該做什么、不該做什么??梢约由隙鄠€(gè)注解,加上的實(shí)際是注解類的對象:@interfaceA。 main()方法必須放在一個(gè)類下,但與這個(gè)類不一定有所屬關(guān)系。 在注解類A上加注解B,這個(gè)注解B只為這個(gè)注解類A服務(wù),B稱為“元注解”。類似的還有元信息、元數(shù)據(jù)。元注解有2個(gè):Rentention和Target。對注解類的注解,可以理解為注解類的屬性。 Rentention注解類 注解的生命周期:Java源文件—》class文件—》內(nèi)存中的字節(jié)碼。編譯或者運(yùn)行時(shí),都有可能會取消注解。Rentention的3種取值意味讓注解保留到哪個(gè)階段,RententionPolicy.SOURCE、RententionPolicy.CLASS(默認(rèn)值)、RententionPolicy.RUNTIME。 @Override、@SuppressWarnings是默認(rèn)保留到SOURCE階段;@Deprecated是保留到RUNTIME階段。 Rentention相當(dāng)于注解類的一個(gè)屬性,因?yàn)镽entention的值不同,注解類保留到的階段不同。注解類內(nèi)部Rentention的值使用value表示,例如,@Deprecated中,value=Runtime。 Rentention的值是枚舉RententionPolicy的值,只有3個(gè):SOURCE、CLASS、RUNTIME。 Target注解類 性質(zhì)和Rentention一樣,都是注解類的屬性,表示注解類應(yīng)該在什么位置,對那一塊的數(shù)據(jù)有效。例如,@Target(ElementType.METHOD) Target內(nèi)部的值使用枚舉ElementType表示,表示的主要位置有:注解、構(gòu)造方法、屬性、局部變量、函數(shù)、包、參數(shù)和類(默認(rèn)值)。多個(gè)位置使用數(shù)組,例如,@Target({ElementType.METHOD,ElementType.TYPE})。 類、接口、枚舉、注解這一類事物用TYPE表示,Class的父類,JDK1.5的新特性。 注解的基本屬性 屬性,給注解提供更加詳細(xì)的信息。 注解相當(dāng)于接口,屬性相當(dāng)于方法。例如,@ItcastAnnotation(color="black"),給屬性賦值,取值時(shí)類似調(diào)用方法,例如,System.out.println(annotation.color());。所有的屬性必須全部出現(xiàn),除非有缺省值。 如果只有value屬性,沒有其他屬性,可以不寫=,只針對value,例如,@SuppressWarnings("Deprecation")?;蛘哂衅渌麑傩远矣腥笔≈?,例如,String color() default "blue";,此時(shí)value單獨(dú)出現(xiàn),不用=。 獲得注解的屬性的值,例如 if(AnnotationDemo.class.isAnnotationPresent(ItcastAnnotation.class)){ ItcastAnnotation annotation = (ItcastAnnotation)AnnotationDemo.class.getAnnotation(ItcastAnnotation.class); System.out.println(annotation.color()); } } 利用反射獲得注解的對象,在讓該對象調(diào)用屬性對應(yīng)的方法。注意類型轉(zhuǎn)換。 Rentention和Target也是屬性,都是value對應(yīng)的值,值的類型分別是RententionPolicy和ElementType,例如,@Retention(value=RetentionPolicy.RUNTIME)。 注解的高級屬性 給注解增加高級屬性,數(shù)組、枚舉、注解。 數(shù)組類型的屬性 例如,int[] arr() default {3,7,5};,MyAnnotation(arr={3,7,6})。如果數(shù)組只有1個(gè)元素,可以不加{}。@Target({ElementType.METHOD,ElementType.TYPE})也是數(shù)組類型的屬性。 枚舉類型的屬性 //注解類內(nèi)部的內(nèi)容 EnumerationDemo.TrafficLamp lamp() default EnumerationDemo.TrafficLamp.RED; //調(diào)用注解的類上 @ItcastAnnotation(lamp=EnumerationDemo.TrafficLamp.YELLOW) //對注解進(jìn)行操作 System.out.println(annotation.lamp().nextLamp().name()); 注解類型的屬性 將一個(gè)注解類作為屬性加入到另一個(gè)注解類中。 MetaAnnotation annotationAtt() default @MetaAnnotation("Jobs") @ItcastAnnotation(annotationAtt=@MetaAnnotation("Kim")) annotation.annotationAtt().value() 注解的返回值可以是8個(gè)基本類型、String、Class、枚舉以及前面類型的數(shù)組,內(nèi)部還有屬性。 需要詳細(xì)學(xué)習(xí)注解,可以通過java語言規(guī)范,即languagespecification。 |
|
|