內省、JavaBean、PropertyDescriptor類、Introspector類、BeanUtils工具包、注解、Rentention、Target、注解的基本屬性和高級屬性


本文轉載自:http://blog.sina.com.cn/s/blog_5d65a16901011kom.html

關鍵字:內省、JavaBean、PropertyDescriptor類、Introspector類、BeanUtils工具包、注解、Rentention、Target、注解的基本屬性和高級屬性

內省IntroSpector

JavaBean主要用於傳遞數據信息,其方法用於訪問私有變量,且方法名符合某種規則。

如果在兩個模塊之間傳遞信息,可以將信息封裝進JavaBean中,這種對象稱為“值對象”(Value Object),或“VO”。方法比較少。這些信息儲存在類的私有變量中,通過set()、get()獲得。

內省主要是對JavaBean進行操作。JavaBean內部的方法要按照某種規則命名,例如void setAge(int age)、int getAge()。JavaBean可以作為普通類進行操作;普通類如果內部有set()、get()方法,也可以當做JavaBean使用。

JavaBean的屬性是通過get()和set()方法推斷出來的,即去掉get、set后的字母,例如,屬性為age,而不是成員變量,因為成員變量看不見。

獲得屬性名的規則:如果屬性名的第二個字母是小寫,則把第一個字母小寫。例如,gettime—>time,setTime—>time,getCPU—>CPU。

JavaBean處理的好處:

1、JavaEE中許多地方需要使用JavaBean。

2、JDK給JavaBean提供的API稱為內省。

 

PropertyDescriptor類

PropertyDescriptor類表示JavaBean類通過存儲器導出一個屬性。主要方法:

1、getPropertyType(),獲得屬性的Class對象。

2、getReadMethod(),獲得用於讀取屬性值的方法;getWriteMethod(),獲得用於寫入屬性值的方法。

3、hashCode(),獲取對象的哈希值。

4、setReadMethod(Method readMethod),設置用於讀取屬性值的方法;setWriteMethod(MethodwriteMethod),設置用於寫入屬性值的方法;

導包java.bean.*;

通過屬性名獲取對應的值,利用反射方法,如下:

ReflectPoint pt1 = new ReflectPoint(7,9);
String propertyName = "x";//給一個屬性,獲取值
PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadMethod();//Read對應get()方法
Object reValue = methodGetX.invoke(pt1);

 

給某個屬性設置值,如下:

String propertyName2 = "y";//給一個屬性,設置值
PropertyDescriptor pd2 = new PropertyDescriptor(propertyName2,pt1.getClass());
Method methodSetY = pd2.getWriteMethod();//Write對應set()方法
methodSetY.invoke(pt1,3);

 

右鍵—》Source—》Generate Geters and Setters,創建get()和set()方法。

選擇一些代碼,右鍵—》Refactor—》Extract Method,創建一個方法,提高復用性。

 

Introspector類

將JavaBean中的屬性封裝起來進行操作。在程序把一個類當做JavaBean來看,就是調用Introspector.getBeanInfo()方法,得到的BeanInfo對象封裝了把這個類當做JavaBean看的結果信息,即屬性的信息。需要導包java.beans.*。

getPropertyDescriptors(),獲得屬性的描述,可以采用遍歷BeanInfo的方法,來查找、設置類的屬性。

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;

}

通過這兩個類的比較可以看出,都是需要獲得PropertyDescriptor,只是方式不一樣:前者通過創建對象直接獲得,后者需要遍歷,所以使用PropertyDescriptor類更加方便。

 

BeanUtils工具包

為JavaBean提供更多、放方便的功能。

beanutils.jar = beanutils-core.jar + beanutils-bean-collections.jar,可以通過BuildPath,添加額外的jar包,或者工程下建立lib目錄,將jar包復制進來,再加載這個jar包:右鍵—》add to BuildPath。使用時需要導包:org.apache.commons.beanutils.BeanUtils。

需要配合使用acpche提供的日志包:logging

獲得屬性的值,例如,BeanUtils.getProperty(pt1,"x"),返回字符串

設置屬性的值,例如,BeanUtils.setProperty(pt1,"y",22),參數是字符串或基本類型自動包裝。設置屬性的值是字符串,獲得的值也是字符串,不是基本類型。

BeanUtils的特點:

1、對基本數據類型的屬性的操作:在WEB開發、使用中,錄入和顯示時,值會被轉換成字符串,但底層運算用的是基本類型,這些類型轉到動作由BeanUtils自動完成。

2、對引用數據類型的屬性的操作:首先在類中必須有對象,不能是null,例如,private Date birthday=new Date();。操作的是對象的屬性而不是整個對象,例如,BeanUtils.setProperty(pt1,"birthday.time",121);

Java7的新特性:Map和JavaBean之間可以進行相互轉換,key是屬性,value是值。

describe:JavaBean—>Map;populate:Map—>JavaBean。例如:

Map map = (name:Kim,age:18);

BeanUtils.setProperty(map,"name","Kim");

  copyProperties(Object dest, Objectorig),將一個對象的屬性值復制到另一個對象的屬性,需要保證屬性一致。

 

PropertyUtils類

和BeanUtils不同在於,運行getProperty、setProperty操作時,沒有類型轉換,使用屬性的原有類型或者包裝類。

 

注解Annotation

JDK1.5出現的新特性。在java.lang.annotation包中。

對於過時的語句,java會提示過時了,通過@SuppressWarnings("Deprecation")在DOS中取消提示,但Eclipse無法取消。這就是注解,相當於標記。編譯器、開發工具、javac通過反射獲得注解里的內容,進而明確應該做什么、不應該做什么。注解可以加在包、類、屬性、方法、參數及局部變量之上。

一個注解就是一個類。@SuppressWarnings,取消警告@Deprecated,已過時,老版可以用,新版無法用。

HashSet集合中,對象必須覆蓋Object類的equals()方法,否則會繼續使用Object類的equals()方法進行比較,錯誤的比較方法。覆蓋equals()方法,參數必須一致,為了防止錯誤寫入本類的對象,加入@Override,必須正確覆蓋父類方法,不是創建新方法。

 

注解的應用

在源程序中,調用一個類,這個類會用到注解,需要先准備好注解類,類在調用注解類的對象。注解類的寫法類似接口,@interface。先寫好注解類A,將注解放在類B中,類C在調用類B時通過反射獲得注解類A的內容,進而明確該做什么、不該做什么。可以加上多個注解,加上的實際是注解類的對象:@interfaceA。

main()方法必須放在一個類下,但與這個類不一定有所屬關系。

在注解類A上加注解B,這個注解B只為這個注解類A服務,B稱為“元注解”。類似的還有元信息、元數據。元注解有2個:Rentention和Target。對注解類的注解,可以理解為注解類的屬性。

 

 

Rentention注解類

注解的生命周期:Java源文件—》class文件—》內存中的字節碼。編譯或者運行時,都有可能會取消注解。Rentention的3種取值意味讓注解保留到哪個階段,RententionPolicy.SOURCE、RententionPolicy.CLASS(默認值)、RententionPolicy.RUNTIME。

@Override、@SuppressWarnings是默認保留到SOURCE階段;@Deprecated是保留到RUNTIME階段。

Rentention相當於注解類的一個屬性,因為Rentention的值不同,注解類保留到的階段不同。注解類內部Rentention的值使用value表示,例如,@Deprecated中,value=Runtime。

Rentention的值是枚舉RententionPolicy的值,只有3個:SOURCE、CLASS、RUNTIME。

 

Target注解類

性質和Rentention一樣,都是注解類的屬性,表示注解類應該在什么位置,對那一塊的數據有效。例如,@Target(ElementType.METHOD)

Target內部的值使用枚舉ElementType表示,表示的主要位置有:注解、構造方法、屬性、局部變量、函數、包、參數和類(默認值)。多個位置使用數組,例如,@Target({ElementType.METHOD,ElementType.TYPE})。

類、接口、枚舉、注解這一類事物用TYPE表示,Class的父類,JDK1.5的新特性。

 

注解的基本屬性

屬性,給注解提供更加詳細的信息。

注解相當於接口,屬性相當於方法。例如,@ItcastAnnotation(color="black"),給屬性賦值,取值時類似調用方法,例如,System.out.println(annotation.color());。所有的屬性必須全部出現,除非有缺省值。

如果只有value屬性,沒有其他屬性,可以不寫=,只針對value,例如,@SuppressWarnings("Deprecation")。或者有其他屬性而且有缺省值,例如,String color() default "blue";,此時value單獨出現,不用=。

獲得注解的屬性的值,例如

if(AnnotationDemo.class.isAnnotationPresent(ItcastAnnotation.class)){

ItcastAnnotation annotation =

(ItcastAnnotation)AnnotationDemo.class.getAnnotation(ItcastAnnotation.class);

System.out.println(annotation.color());

}

}

利用反射獲得注解的對象,在讓該對象調用屬性對應的方法。注意類型轉換。

Rentention和Target也是屬性,都是value對應的值,值的類型分別是RententionPolicy和ElementType,例如,@Retention(value=RetentionPolicy.RUNTIME)。

 

注解的高級屬性

給注解增加高級屬性,數組、枚舉、注解。

數組類型的屬性

例如,int[] arr() default {3,7,5};,MyAnnotation(arr={3,7,6})。如果數組只有1個元素,可以不加{}。@Target({ElementType.METHOD,ElementType.TYPE})也是數組類型的屬性。

枚舉類型的屬性

//注解類內部的內容

EnumerationDemo.TrafficLamp lamp() default EnumerationDemo.TrafficLamp.RED;

//調用注解的類上

@ItcastAnnotation(lamp=EnumerationDemo.TrafficLamp.YELLOW)

//對注解進行操作

System.out.println(annotation.lamp().nextLamp().name());

注解類型的屬性

將一個注解類作為屬性加入到另一個注解類中。

MetaAnnotation annotationAtt() default @MetaAnnotation("Jobs")

@ItcastAnnotation(annotationAtt=@MetaAnnotation("Kim"))

annotation.annotationAtt().value()

注解的返回值可以是8個基本類型、String、Class、枚舉以及前面類型的數組,內部還有屬性。

需要詳細學習注解,可以通過java語言規范,即languagespecification。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM