天天看點

黑馬程式員_高新技術(二)

----------------------------------------------------------------------------- android教育訓練、java教育訓練、期待與您交流! --------------------------------------------------------------------------------

Beanutils工具包

用ecplice加入jar包,分别導入BeanUtils和loading包,并設定BuildPath。

用BeanUtils代替上面的内省操作。

get屬性傳回的結果為字元串,set可設定任意類型的的對象,通常使用字元串。

PropertyUtils:get屬性傳回的結果為該屬性本來的類型,set屬性隻接受該屬性本來的類型。

Java的三個基本注解

注解:等于為程式打上了某種标記,可以加在類,包,字段,方法,方法的參數及局部變量上。

@Deprecated:标記此程式元素已過時,通常是因為它很危險或存在更好的選擇。

@SuppressWarnings:取消顯示指定的編譯器警告。

@Override:表示一個方法聲明打算重寫超類中的另一個方法聲明。如果方法利用此注釋類型進行注解但沒有重寫超類方法,則編譯器會生成一條錯誤消息。

注解的應用

元注解@Retention--定義注解類的存在區域,有三種取值:RetentionPolicy.SOURCE、RetentionPolicy.CLASS、 RetentionPolicy.RUNTIME,分别對應java源檔案、class檔案、記憶體中的位元組碼。

元注解@Target:确定注解類可用範圍,取值ElementType.METHOD···

為注解增加基本屬性

定義基本類型的屬性

在注解類中增加String color();

引用:@MyAnnotation(color=“red”)

用反射獲得注解對應的執行個體對象後,再通過對象調用屬性對應的方法。

MyAnnotationa=(MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation)

System.out.println(a.color);

為屬性定義預設值Stringcolor() default “red”;

Value屬性  String value();

如果一個 注解隻有一個名稱為value的屬性,且你隻想設定value的屬性,可以省略,@MyAnnotation(“red”);

為注解增加進階屬性

數組類型的屬性

int[] arrayAttr () default{1,2,4,5};

@MyAnnotation(arrayAttr={2,3,4});如果數組中隻有一個元素,則可以省略大括号。

枚舉類型的屬性

EnumTest.TracfficLamp lamp() default   EnumTest.TracfficLamp.RED;

 @MyAnnotation(lamp = EnumTest.TracfficLamp.YELLOW);

注解類型的屬性

MetaAnnotation annotationAttr() default @MetaAnnotation(“lhm”);

 @ MyAnnotation(annotationAttr = @MetaAnnotation(“flx”));MetaAnnotation為注解類

Class類型的屬性

Class annotationClass() defaultString.class;

@MyAnnotation(annotationClass=String.class);

泛型

Jdk1.5的集合類在希望你在定義集合時,明确表示你要向集合中裝哪種類型的資料,無法加入指定類型以外的資料。

ArrayList<Integer> c=newArrayList<<Integer>();

c.add(“abc”);//編譯報錯

泛型是提供給java編譯器使用的,讓編譯器擋住程式的非法輸入,對于參數化的泛型,getClass傳回值和原始類型完全一樣。由于編譯生成的位元組碼會去掉泛型的資訊,隻要跳過編譯器,就可以往泛型集合中加入其它類型的資料,如:用反射得到集合,再調用其add方法即可。

了解泛型

ArrayList<E>類定義和ArrayList<Integer>類引用中涉及的術語:

  1、整個ArrayList<E>稱為泛型類型

 2、ArrayList<E>中E稱為類型變量或類型參數

 3、整個ArrayList<Integer>稱為參數化的類型

 4、ArrayList<Integer>中的Integer叫類型參數的執行個體或實際類型參數

 5、ArrayList<Integer>中的<>念typeof

  6、ArrayList稱為原始類型

參數化類型與原始類型的相容性-編譯警告

Collection<String> = new Vector();

Collection = new Vector<String >();

參數化類型不考慮類型參數的繼承關系

Vector<String> v = new Vector<Object>();//錯!

Vector<Object> v = new Vector<String>();//錯!

在建立數組執行個體時,數組的元素不能使用參數化的類型

Vector<Integer> v[] = new Vector<Integer>[10];

Vector v1 = newVector<Integer>();

Vector<Object> v = v1;     //編譯可以通過!編譯器隻會按行解釋

泛型的?通配符及擴充

<?>可以引用各種參數化的類型,可以調用與參數無關的方法,不能調用與參數有關的方法

限定通配符的上邊界

正确:Vector<? extends Number> v=newVector<Integer>();

錯誤:Vector<? extends Number> v=new Vector<String>();

限定通配符的下邊界

正确:Vector<? Super Integer> v=newVector<Number>();

錯誤:Vector<? extends Integer > v=new Vector<Byte>();

通配符包括自己

定義泛型的方法

交換數組中兩個元素的位置的泛型方法定義如下:

private static<T> void swap(T[] a,int i,int j){

Ttemp = a[i];

a[i]= a[j];

a[j]= temp; }

用于放置泛型的類型參數的尖括号應出現在方法的所有修飾符之後和傳回類型之前。

隻有引用類型才能作為泛型方法的實際參數,基本類型則不可以如:swap(new int[]{1,3},1,2);

定義泛型時也可以使用extends修飾符,如<Vextends Serializable&cloneable> void method();

也可以用類型變量表示異常,可以用于方法的throws清單中,但不能用于catch中。

泛型中可以有多個類型參數,在定義它們的尖括号中用逗号分開。Publicstatic <K,V> V getValue(K key) {return map.get(key);}

定義泛型類

類中的多個方法要使用同一個泛型參數,此時要定義類級别的泛型。

public classGenericDao<T>{

        private Tfield1;

        public void save<Tobj>{}

        public T getById(intID){}

}

類級别的泛型是根據引用類名指定的泛型資訊來參數化變量的.

GenericDao<String> dao=null;

new GenericDao<String>();

注意

1、在對泛型參數化時,必須是引用類型,不能是基本類型。

2、當一個類被聲明為泛型時,隻能被執行個體變量和方法調用(還有内嵌類),而不能被靜态變量和靜态方法調用。因為類靜态成員是被所有參數化的類所共享的,是以靜态成員不應該擁有類級别的類型參數。

通過反射獲得泛型的參數化類型

Vector<Date> v= new Vector<Date>();

通過v.getClass()是無法獲得泛型的參數化類型的。

将其傳遞給一個方法,可實作此功能。

public static void applyVector(Vector<Date> v){}

Method applyMethod =GenericTest.class.getMethod("applyVector",        Vector.class);

Type[]types = applyMethod.getGenericParameterTypes();

ParameterizedTypepType =        (ParameterizedType)types[0];

System.out.println(pType.getRawType());//Vector

System.out.println(pType.getActualTypeArguments()[0]);//Date

類加載器的委托機制

當java虛拟機加載類時,到底用哪個類加載器?

 首先目前線程的類加載器去加載線程中的第一個類

 如果類A引用了類B,那麼java虛拟機将使用加載類A的類加載器去加載類B

 還可以直接調用ClassLoader.loaderClass()方法來指定某個類加載器去加載

每個類加載器加載時,又委托給其上級的類加載器。

當所有祖宗類加載器沒有加載到該類,則回到發起者類加載器,還加載不到,則抛出ClassNoFoundException,不是再找發起者類加載器和兒子,因為沒有getChild方法。——從上到下的加載。

自定義類加載器

工作機制

父類——>loadClass/findClass()/得到class檔案的内容轉換成位元組碼—>difineClass()/将一個byte 數組轉換為 Class 類的執行個體

實作步驟

 自定義的類加載器必須繼承ClassLoader

 覆寫findClass方法

 覆寫difineClass()方法

用自定義加載類實作加密及解密-難!

檢視視訊及源檔案 MyClassLoader.class

----------------------------------------------------------------------------- android教育訓練、java教育訓練、期待與您交流!--------------------------------------------------------------------------------

詳細請檢視:http://edu.csdn.net/heima/