---------- android培訓、java培訓、期待與您交流! ----------
一、JavaBean
* 通過內省引入JavaBean:內省對應的英文全程是IntroSpector。在Java中,其作用主要針對JavaBean進行操作。
(一)概述
(1)JavaBean是一種特殊的Java類,主要用于傳遞數據信息,這種Java類中的方法主要用于訪問私有的字段,且方法符合某種特殊的命名規則。
(2)如果要在兩個模塊之間傳遞多個信息,可以將這些信息封裝到一個JavaBean中,這種JavaBean的實例對象通常稱之為值對象(Value Object,簡稱VO)
(3)JavaBean的屬性是根據其中的setter和getter方法來確定的,而不是根據其中的成員變量。
如方法名為setId,則中文意思是設置Id,getId也是如此;去掉set或者get前綴,剩余部分就是屬性名稱。如果剩余部分的第二個字母小寫,則把剩余部分改為小寫。如:
Ø getAge/setAge-->age;
Ø gettime-->time;
Ø setTime-->time;
Ø getCPU-->CPU;
總之,一個類被當作javaBean使用時,JavaBean的屬性是根據方法名推斷出來的,它根本看不到java類內部的成員變量。
(二)JavaBean好處
符合JavaBean特點的類可以當作普通類一樣使用,把它當JavaBean用會帶來一些額外的好處:
1、在Java EE開發中,經常要使用到JavaBean,很多環境就要求按JavaBean方式進行操作。
2、JDK中提供了對JavaBean進行操作的一些API,這套API就稱為內省。用內省這套api操作JavaBean比用普通類的方式更方便。
(三)內省的簡單操作
1 import java.beans.BeanInfo; 2 import java.beans.IntrospectionException; 3 import java.beans.Introspector; 4 import java.beans.PRopertyDescriptor; 5 import java.lang.reflect.InvocationTargetException; 6 import java.lang.reflect.Method; 7 import java.util.Map; 8 import org.apache.commons.beanutils.BeanUtils; 9 import org.apache.commons.beanutils.PropertyUtils;10 public class IntroSpectorTest {11 public static void main(String[] args) throws Exception {12 ReflectPoint pt1 = new ReflectPoint(3,5);13 String propertyName = "x"; 14 Object retVal = getProperty(pt1, propertyName); 15 Object value = 7; 16 setProperties(pt1, propertyName, value);17 System.out.println(pt1.getX());18 }19 private static void setProperties(Object pt1, String propertyName,20 Object value) throws IntrospectionException,21 IllegalaccessException, InvocationTargetException {22 PropertyDescriptor pd2 = new PropertyDescriptor(propertyName,pt1.getClass());23 Method methodSetX = pd2.getWriteMethod();24 methodSetX.invoke(pt1,value);25 }26 private static Object getProperty(Object pt1, String propertyName)27 throws IntrospectionException, IllegalAccessException,28 InvocationTargetException {29 PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());30 Method methodGetX = pd.getReadMethod();31 Object retVal = methodGetX.invoke(pt1);32 return retVal;33 }34 }
(四)對JavaBean的復雜內省操作
1、操作步驟:
(1)在IntroSpector類中有getBeanInfo(Class cls)的方法,通過此方法獲取BeanInfo實例。參數是相應對象的字節碼,即Class對象。
(2)BeanInfo類中有getPropertyDescriptors()的方法,可獲取所有的JavaBean類中的屬性信息,返回一個PropertyDescriptor[]。
(3)在通過遍歷的形式,獲取與想要的那個屬性信息。
2、以getX為例,步驟實現的代碼示例:
1 private static Object getProperty(Object pt1, String propertyName) 2 throws IntrospectionException, IllegalAccessException, 3 InvocationTargetException { 4 BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass()); 5 PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); 6 Object retVal = null; 7 for(PropertyDescriptor pd : pds){ 8 if(pd.getName().equals(propertyName)) 9 {10 Method methodGetX = pd.getReadMethod();11 retVal = methodGetX.invoke(pt1);12 break;13 }14 }15 return retVal;16 }(五)BeanUtils工具包
1、beanutils包下載及添加
(1)下載地址:http://commons.apache.org/proper/commons-beanutils/
(2)兩種添加方式:
Ø 方式1:項目上“右鍵”—— Build Path —— Configure Build Path —— 選擇Liberiers標簽 —— AddExternal Jars —— 選擇要導入的jar包。這種方式屬于“本地添加”,存在的問題就是如果jar路徑發生變化,項目就不能使用到這個jar包。
Ø 方式2:在項目中建立一個lib目錄,專門用于存放項目所使用到的jar工具包。將要使用到jar包復制進來。在Eclipse的Package Explorer面板中,在jar文件上點右鍵——選擇Builder Path——Add to BiuldPath,添加完成。這樣做的好處:jar隨項目一起移動。
2、可能出現的問題
問題:添加beanutils工具包后,可能會出現org/apache/commons/logging/logFactory找不到
解決方法:下載commons-logging.jar,同beanutils添加步驟一樣,添加日志jar包即可。
3、BeanUtils工具應用,代碼示例
1 import org.apache.commons.beanutils.BeanUtils; 2 import org.apache.commons.beanutils.PropertyUtils; 3 public class IntroSpectorDemo { 4 public static void main(String[] args) throws Exception { 5 reflectPoint rp1 = new reflectPoint(3,5); 6 String propertyName = "x"; 7 // 用BeanUtils工具包的方法 8 System.out.println(BeanUtils.getProperty(rp1, "x"));//get 9 BeanUtils.setProperty(rp1, "x", "9");//set10 System.out.println(rp1.getX());11 }12 }4、BeanUtils和PropertyUtils的區別?
BeanUtils工具包中還有一個工具類PropertyUtils,用法跟BeanUtils一樣。區別在于:
(1)BeanUtils會對JavaBean的屬性的類型進行轉換,如屬性本身是integer,會轉換為String。
(2)PropertyUtils以屬性本身的類型進行操作。
1 //用BeanUtils工具包的工具類BeanUtils方法2 BeanUtils.setProperty(rp1, "x", "9");//set,9是String3 System.out.println(BeanUtils.getProperty(rp1, "x"));//get4 System.out.println(BeanUtils.getProperty(rp1, "x").getClass().getName());//java.lang.String5 6 //BeanUtils工具包中的PropertyUtils的操作7 PropertyUtils.setProperty(rp1, "x", 9);//9是Integer8 System.out.println(PropertyUtils.getProperty(rp1, "x"));9 System.out.println(PropertyUtils.getProperty(rp1,"x").getClass().getName());//java.lang.Integer
=============================Annotation(注解)==============================
二、注解(Annotation)
(一)概述
1、注解(Annotation)相當于一種標記,在程序中加了注解就等于為程序打上了某種標記。
2、標記可以加在包,類,字段,方法,方法的參數以及局部變量上。
3、格式:@ 注解名稱
(二)Java提供的幾個基本注解
1、@Deprecated:表示告知調用者,該成員函數、字段等已經過時,不再推薦使用。
(1)讓程序部提示函數棄用(過時)?需要在main方法前面,寫上@Suppress Warings(“deprecation”)
(2)注解一個函數過時?在函數的上一行,寫上@deprecated
2、@Override:表示覆蓋父類方法。
(三)注解的應用結構圖

(四)自定義注解及其應用
1、格式:@interface name{statement},如public @interface MyAnnotation{}
2、在類上添加注解:
@MyAnnotation
public class AnnotationTest{}
3、元注解(@Retention、@Target)
Ø Retetion:用于說明注解保留在哪個階段(即注解的生命周期)。一個注解的生命周期包括:java源文件→class文件→內存中的字節碼[雨林木風1],其有三種取值:
(1)RetetionPolicy.SOURSE:java源文件時期,如@Overried和@SuppressWarning
(2)RetetionPolicy.CLASS: class文件時期(默認階段)
(3)RetetionPolicy.RUNTIME:運行時期,如@Deprecated
如:在某注解類上加@Retention(RetentionPolicy.RUNTIME),表示此注解會一直存在。
Ø Target:用于說明注解類的使用范圍(如:作用在方法上、類上,默認值是任何地方)
其值可設置為枚舉類ElementType類中的任何一個,包括:包、字段、方法、方法參數、構造器、類等值。取值為:
ANNOTATION_TYPE:注釋類型聲明;
CONSIRUCTOR:構造器聲明;
FIELD:字段聲明;
LOCAL_VARIABLE:局部變量聲明;
METHOD:方法聲明;
PACKAGE:包聲明;
PARAMETER:參數聲明;
TYPE:類、接口(包含注釋類型)或枚舉聲明;
注意:其中代表類的值是TYPE。因為class、enum、interface和@interface等都是平級的,所以統屬于Type。不可用CLASS表示。
4、注解代碼示例
1 import java.lang.annotation.ElementType; 2 import java.lang.annotation.Retention; 3 import java.lang.annotation.RetentionPolicy; 4 import java.lang.annotation.Target; 5 @Retention(RetentionPolicy.RUNTIME) 6 @Target({ElementType.METHOD,ElementType.TYPE}) 7 //注解類 8 @interface MyAnnotation { 9 }10 @MyAnnotation11 public class AnnotationDemo {12 @SuppressWarnings("deprecation")//此注解用于表明不提示過時信息13 public static void main(String[] args) {14 System.runFinalizersOnExit(true); //此方法已過時15 //判斷此類是否有MyAnnotation注解16 if (AnnotationDemo.class.isAnnotationPresent(MyAnnotation.class)) {17 //如果有,則獲取該注解18 MyAnnotation annotation = AnnotationDemo.class.getAnnotation(MyAnnotation.class);19 System.out.println(annotation);20 }21 }22 }(五)為注解增加基本屬性
1、注解屬性:為注解的參數添加的屬性。例如:@MyAnnotation(color="red")
2、定義基本類型的屬性
(1)在注解類中增加屬性:String color();
(2)定義缺省格式:String value() default “heima;
3、注解屬性應用:
直接在注解的括號中添加自身的屬性:@MyAnnotation(color="red")
4、value屬性:如果注解中有一個名稱為value的屬性,且只想設置value屬性(即其他屬性都采用默認值或只有一個value屬性),那么可以省略value=部分。例如:
String value() default "red";
@MyAnnotation("green")
5、說明:
(1)可以為屬性值指定缺省值(default),應用時同樣可以重新設置屬性值。
(2)用反射方式獲得注解對應的實例對象后,可以通過該對象調用屬性對應的方法來獲取屬性值。
6、代碼示例:
1 import java.lang.annotation.Retention; 2 import java.lang.annotation.RetentionPolicy; 3 @Retention(RetentionPolicy.RUNTIME) 4 public @interface MyAnnotation{ 5 String color() default "blue"; 6 String value(); 7 } 8 9 @MyAnnotation(color="red",value="abc")10 public class AnnotationTest {11 @SuppressWarnings("deprecation")12 @MyAnnotation("xyz")13 public static void main(String[] args) throws Exception{14 System.runFinalizersOnExit(true);15 if(AnnotationTest.class.isAnnotationPresentMyAnnotation.class)){16 System.out.println(annotation.color());17 System.out.println(annotation.value());18 }19 }20 }(六)為注解增加高級屬性
1、數組類型的屬性:
如:int[]arrayArr() default {1,2,3}
應用:@MyAnnotation(arrayArr={2,3,4})
注:如果數組屬性中只有一個元素,這時候屬性值部分可以省略大括。
2、枚舉類型的屬性:(定義了一個枚舉類TrafficLamp,它是EnumTest的內部類,其值是交通燈的三色)
定義:EnumTest.TrafficLamplamp();
應用:@MyAnnotation(lamp=EnumTestTrafficLamp.GREEN)
3、注解類型的屬性:(定義一個注解類:MetaAnnotation,其中定義了一個屬性:String value())
定義:MetaAnnotation annotation() default @MetaAnnotation(”xxx”);
應用:@MyAnnotation(annotation=@MetaAnnotation(”yyy”))//重新賦值
4、Class類型的屬性:
定義:Class cls();
應用:@MyAnnotation(cls=AnnotationDemo.class)
注:這里的.class必須是已定義的類,或是已有的字節碼對象
5、注解的詳細語法可通過查看java語言規范了解即javaLanguage Specification
6、代碼示例:
1 import java.lang.annotation.ElementType; 2 import java.lang.annotation.Retention; 3 import java.lang.annotation.RetentionPolicy; 4 import java.lang.annotation.Target; 5 @Retention(RetentionPolicy.RUNTIME)//元注釋 6 @Target({ElementType.METHOD,ElementType.TYPE})//元注解,指定使用范圍 7 //注解類 8 public @interface MyAnnotation { 9 String color() default "red" ;10 String value();11 int[] arr() default {1,2,3};12 EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.GREEN;13 MetaAnnotation annotation() default @MetaAnnotation("heima");14 Class clazz() default System.class;15 }16 17 //注解類的應用,給屬性賦值或者重新賦值 18 @MyAnnotation(lamp=EnumTest.TrafficLamp.YELLOW,value="itheima", clazz=AnnotationDemo.class,annotation=@MetaAnnotation("itheima"))19 public class AnnotationDemo {20 @SuppressWarnings("deprecation")21 @MyAnnotation("Method")//自定義注解應用在方法上22 public static void main(String[] args) throws NoSuchMethodException, SecurityException {23 System.runFinalizersOnExit(true); //一個過時方法24 //判斷此類是否有MyAnnotation注解25 if (AnnotationDemo.class.isAnnotationPresent(MyAnnotation.class)) {26 //如果有,則獲取該注解27 MyAnnotation annotation =AnnotationDemo.class.getAnnotation (MyAnnotation.class);28 System.out.println(annotation);//@cn.itheima.Demo.MyAnnotation()29 System.out.println(annotation.color());30 System.out.println(annotation.value());31 System.out.println(annotation.arr().length);32 System.out.println(annotation.lamp());33 System.out.println(annotation.annotation().value());34 System.out.println(annotation.clazz());35 }36 //獲取方法上的注解37 Method mainMethod = AnnotationDemo.class.getMethod("main",String[].class);38 MyAnnotation annotationMethod = (MyAnnotation) mainMethod.getAnnotation (MetaAnnotation.class);39 SuppressWarnings sw=mainMethod.getAnnotation(SuppressWarnings.class);40 System.out.println(sw);41 System.out.println(annotationMethod);42 }43 }---------- android培訓、java培訓、期待與您交流! ----------
新聞熱點
疑難解答