【重學Java】(二)註解與反射

1.註解的意義

註解本身沒有意義,它是作爲一種標記或者註釋存在。需要結合反射、插樁纔有作用

jdk1.5引入,對於被註解的代碼沒有影響

2.元註解

是用於註解的註解:meta-annotation

Target:註解的使用範圍

public enum ElementType {
 
    TYPE, // 類、接口、枚舉類
 
    FIELD, // 成員變量(包括:枚舉常量)
 
    METHOD, // 成員方法
 
    PARAMETER, // 方法參數
 
    CONSTRUCTOR, // 構造方法
 
    LOCAL_VARIABLE, // 局部變量
 
    ANNOTATION_TYPE, // 註解類
 
    PACKAGE, // 可用於修飾:包
 
    TYPE_PARAMETER, // 類型參數,JDK 1.8 新增
 
    TYPE_USE // 使用類型的任何地方,JDK 1.8 新增
 
}

Retension:註解保留的時間範圍

public enum RetentionPolicy {
 
    SOURCE,    // 源文件保留
    CLASS,       // 編譯期保留,默認值
    RUNTIME   // 運行期保留,可通過反射去獲取註解信息
}

Documented:用javac生成幫助文檔時,是否保留註解信息

Inherited:被修飾的註解具有繼承性

3.註解的使用場景

(1)source級別:編譯器能獲得註解和註解聲明的類,能夠獲得其所有成員信息,一般用於編譯器生成額外的代碼,如APT技術

(2)class級別:編譯出.class後,通過修改class數據實現修改代碼邏輯的目的,如字節碼增強、插樁等

(3)runtime級別:程序運行期間,通過反射動態獲取註解和類信息,以完成修改,如反射

(4)Android語法檢查,用@DrawableRes檢查參數類型或@IntDef自定義入參類型檢查

4.反射

典型反射代碼應用:反射獲取intent傳值

public static void injectIntent2(Activity activity){
        Class<? extends Activity> cls = activity.getClass();

        Field[] fields = cls.getDeclaredFields();
        for(Field field:fields){
            if(field.isAnnotationPresent(InjectIntent.class)){
                InjectIntent injectIntent = field.getAnnotation(InjectIntent.class);
                String key = injectIntent.value();
                Bundle bundle = activity.getIntent().getExtras();

                field.setAccessible(true);

                try {
                    field.set(activity,bundle.get(key));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }

 

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