Java學習筆記十一

只要做好準備,人生的盡頭也是一段絕美的旅程。——尤金·奧凱利

今日整理記錄內容:
1、(JDK1.5)註解
2、(JDK1.5)泛型

一、(JDK1.5)註解
1、註解就是讓程序在編譯的時候檢測代碼的性質(正確性、過時性等),加不同的註解,編譯期檢測不同的性質;
2、常用於定義框架
3、常用註解 Override、Deprecated、SuppressWarnings
4、Retention:保留註解,共分三個階段(三個常量)
@Retention(RetentionPolicy.SOURCE)—》java文件
@Retention(RetentionPolicy.CLASS)—》保留到編譯時(class文件)
@Retention(RetentionPolicy.RUNTIME)—》保留到運行時
5、定義註解的屬性:返回值類型(不能沒有返回值) 方法名() default 默認值。注意:方法名字是value的屬性、返回值是數組的屬性
解釋:

/*定義的枚舉類*/
public enum MyEnum {
   MATH,ENGLISH,CHINESE;
}

/*自定義的註解類*/
@Retention(RetentionPolicy.RUNTIME)//這是定義要把MyAnnocation註解保留到運行期間
@Target({ElementType.TYPE, ElementType.METHOD})//這是定義MyAnnocation作用在方法和類型上。
public @interface MyAnnocation {

    int value();//當註解中只有一個方法且方法名是value的,則在初始化時可以省略方法名
    String[] getStrArr();//返回值爲數組類型的,有多個元素使用{元素1,元素2,......},如果數組中只用一個元素可省略大括號 {},
    String hsDefault() default "我是默認值,可有可沒有";//這是有默認值的,在初始化註解類時,如果不賦值就是用默認值
    MyEnum getEnum(); //這是返回值爲枚舉類型的

}

/*自定義註解類的使用*/
//此時註解作用到類型上,是符合要求的
@MyAnnocation(getEnum = MyEnum.MATH,
hsDefault = "這是帶有默認值的方法", //這裏是用自己設置的值代替默認值,如果不設置就是使用默認值
getStrArr = { "元素1", "元素2" }, //這裏數組中有多個元素,所以要用大括號括起來。
value = 22)
public class AnnocationTest {

    @MyAnnocation(getEnum = MyEnum.ENGLISH,
            /*這裏不設置有默認值的方法也是可以得*/ 
            getStrArr = "只有一個元素"/*這裏數組中只有一個元素,所以可以省略大括號*/, 
            value = 22)
    public static void testAnnocation(){

    }


    public static void main(String[] args){
        /*我們通過反射技術獲得類上的註解*/
        System.out.println("類上的註解:");
        Annotation[] a1 = AnnocationTest.class.getAnnotations();
        for (Annotation annotation : a1) {
            if(annotation instanceof MyAnnocation){
                MyAnnocation myA1 = (MyAnnocation)annotation;
                String[] retArray = myA1.getStrArr();
                int length = retArray.length;
                for(int i = 0; i < length; i++){
                    System.out.println(retArray[i]);
                }
                System.out.println(myA1.getEnum().name());
                System.out.println(myA1.hsDefault());
                System.out.println(myA1.value());
            }
        }

        /*我們通過反射技術獲得方法上的註解*/
        try {
            System.out.println("方法上的註解:");
            Method method = AnnocationTest.class.getDeclaredMethod("testAnnocation", null);
            Annotation[] a2 = method.getAnnotations();
            for (Annotation annotation : a2) {
                if(annotation instanceof MyAnnocation){
                    MyAnnocation myA1 = (MyAnnocation)annotation;
                    String[] retArray = myA1.getStrArr();
                    int length = retArray.length;
                    for(int i = 0; i < length; i++){
                        System.out.println(retArray[i]);
                    }
                    System.out.println(myA1.getEnum().name());
                    System.out.println(myA1.hsDefault());
                    System.out.println(myA1.value());
                }
            }
        } catch (NoSuchMethodException | SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

輸出結果:
類上的註解:
元素1
元素2
MATH
這是帶有默認值的方法
22

方法上的註解:
只有一個元素
ENGLISH
我是默認值,可有可沒有
22

以上就是自定義註解類以及對於自定義註解類的使用。我們可以自己動手嘗試將@Retention的值設置成RetentionPolicy.SOURCE或RetentionPolicy.CLASS,然後運行查看結果。
動手查看Override、Deprecated、SuppressWarnings註解類的源代碼,看看如何使用。最後結合百度看看每個註解是幹什麼用的就可以了。

//Override類
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

//Deprecated類
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

//SuppressWarnings類
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {    
    String[] value();
}

二、(JDK1.5)泛型
1、是提供給編輯器使用的,給某事物加了指定類型的泛型後,編輯器就會在源程序中阻止非指定類型的數據加入。當編譯器編譯源代碼生成.class文件時,就會將泛型<> “擦去”,也就是說反譯.class文件後“看不到”泛型了
2、這裏所說的 “擦去”、“看不到”,是想法上的,實際上還是會存在,這是會以一種特殊標記的方式存在,某些反編譯器(jd-gui反編譯器)還是可以通過反編譯.class文件得到帶有泛型的源代碼。
3、
ArrayList<E> 整個稱爲泛型類型
ArrayList<E>中的E稱爲類型變量或類型參數
ArrayList<Integer>整個稱爲參數化的類型
ArrayList<Integer>中Integer稱爲類型參數的實例化或實際類型參數
ArrayList稱爲原始類型

4、參數化類型不考慮類型參數的繼承關係。
Vector<String> v = new Vector<Object>();//錯誤
Vector<Object> v = new Vector<String>();//錯誤

5、泛型類型使用了泛型的通配符(?)後,泛型類型的對象不能調用與類型參數有關的方法。
例: Collection<?> cl = new Collection();
cl.add(1);//錯誤,調用了與類型參數有關的方法。

解釋:


獲得某個方法的參數列表(參數列表中有泛型類型)中的實際類型參數
public class GenericTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {
            Method method = GenericTest.class.getDeclaredMethod("testGeneric", Vector.class, String.class);
            Type[] ty1 = method.getGenericParameterTypes();
            for (Type type : ty1) {
                if(type instanceof ParameterizedType){
                    ParameterizedType pty1 = (ParameterizedType)type;
                    System.out.println(pty1.getTypeName());
                    System.out.println(pty1.getOwnerType());//獲得頂層類型。如果當前類型爲頂層,則返回null。
                    System.out.println(pty1.getActualTypeArguments()[0]);
                    System.out.println(pty1.getRawType());
                }
            }

        } catch (NoSuchMethodException | SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /*帶有泛型類型的方法*/
    public static void testGeneric(Vector<Date> vc, String str){

    }
}

輸出結果:
java.util.Vector<java.util.Date>
null
class java.util.Date
class java.util.Vector

//通過反射技術實現向參數化類型的泛型類型中增加不同類型的數據
  /*定義一個實際類型參數爲String的泛型類型*/
        Collection<String> collection = new ArrayList<String>();
        collection.add("字符串1");//向其中增加字符串類型數據
        try {
            /*通過反射技術實現增加不同類型*/
            Method methodAdd = collection.getClass().getMethod("add", Object.class);
             methodAdd.invoke(collection, 1);
             methodAdd.invoke(collection, true);
             System.out.println("集合長度:"+collection.size());
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

學習心得:觀看資料–》思考問題–》實踐證明–》整理記錄 = 有思想的技術大牛!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章