Java注解

元數(shù)據(jù)

元數(shù)據(jù)是指用來描述數(shù)據(jù)的數(shù)據(jù)(“data about data”),簡單的說,就是描述代碼間關(guān)系拴还,代碼本身,資源數(shù)據(jù)等的數(shù)據(jù)鸦难。一般是結(jié)構(gòu)化數(shù)據(jù)(如存儲在數(shù)據(jù)庫里的數(shù)據(jù)根吁,規(guī)定了字段的長度、類型等)合蔽。元數(shù)據(jù)是指從信息資源中抽取出來的用于說明其特征击敌、內(nèi)容的結(jié)構(gòu)化的數(shù)據(jù)。
比如拴事,關(guān)于一本書(信息資源)沃斤,我們在圖書館系統(tǒng)中檢索可以得到題名,版本、出版數(shù)據(jù)刃宵、相關(guān)說明,包括檢索點等衡瓶,這些就是元數(shù)據(jù),用于描述資源的牲证。

Java注解

JDK5.0引入了Annotation的概念來描述元數(shù)據(jù)哮针,在java中,元數(shù)據(jù)是以標簽的形式存在,元數(shù)據(jù)并不會影響程序代碼的編譯和執(zhí)行坦袍。JDK5.0出來后诚撵,java語言中有四種類型,class(類)键闺、enum(枚舉)寿烟、interface(接口)和@interface(注解),他們在java中處于同一級別辛燥。元數(shù)據(jù)在java中筛武,既是由注解來表示的。注解可以在編譯挎塌、類加載和運行時被讀取徘六。
Java的注解本質(zhì)上是一個接口,繼承了接口Annotation的接口榴都,這里的繼承用的是extends待锈。

注解既然和接口類似,就會包含成員:

  • final靜態(tài)屬性嘴高,必須初始化
  • 公共抽象方法竿音,可設(shè)置默認值

@interface隱含繼承Annotation,但是自定義注解不能直接繼承Annotation。直接繼承的是接口拴驮,非注解春瞬。

注解的作用

  1. 編寫文檔(通過代碼里面標識的元數(shù)據(jù)編寫,例如@param,@return)
  2. 代碼分析(可以替代配置文件)
  3. 編譯檢查(通常配合lint使用套啤,如@override 放在方法前宽气,如果你這個方法并不是覆蓋了超類方法,則編譯時就能檢查出。)

Java中自帶的注解

(基本)

  1. @Override(限定重寫父類的方法)
  2. @SuppressWarning(用于抑制編譯器產(chǎn)生警告信息)
  3. @Deprecated(表示"已過時/不建議使用/在后期的API中可能被刪除")
  4. @SafeVarargs(java7新增萄涯,和堆污染有關(guān)绪氛,具體不是很了解)
    (用于標識注解的注解)
  5. @Retention(決定注解存活和讀取時間,它包含一個RetationPolicy的value成員變量涝影,用于指定它所修飾的注解的讀取和存活時間)
    一般的值有:
    • Retationpolicy.CLASS:在類加載的時候解讀钞楼,執(zhí)行的時候,jvm就會拋棄掉。
    • Retationpolicy.ROURCE:存在于源碼中袄琳,在編譯的時候解讀询件,之后就拋棄,不進入類加載和運行環(huán)節(jié)唆樊。
    • Retationnpolicy.RUNTIME:運行時解讀宛琅,可以在運行時通過反射獲取注解,執(zhí)行操作逗旁。
  6. @Target (指定修飾的元素嘿辟,包含一個value值)
    value可選:
    • ElementType.ANNOTATION_TYPE: 指定該Annotation只能修飾Annotation。
    • ElementType.CONSTRUCTOR: 指定只能修飾構(gòu)造器片效。
    • ElementType.FIELD: 指定只能成員變量红伦。
    • ElementType.LOCAL_VARIABLE: 指定只能修飾局部變量。
    • ElementType.METHOD: 指定只能修飾方法淀衣。
    • ElementType.PACKAGE: 指定只能修飾包定義昙读。
    • ElementType.PARAMETER: 指定只能修飾參數(shù)。
    • ElementType.TYPE: 指定可以修飾類膨桥,接口蛮浑,枚舉定義。
  7. @Document(可被javadoc提取成文檔)
  8. @Inherited 被他修飾的Annotation具有繼承性

自定義注解

最簡單的例子只嚣,Android中代替findviewById()對組件進行初始化沮稚。只需要在成員變量組件前加上注解就行,能有效的減少代碼量册舞,可讀性更強蕴掏。

首先定義注解,運行時讀取调鲸,作用于成員變量
寫法和接口雷同
用法是@FindView(R.id.XXX)這里傳入的Id就是這個value的返回值盛杰,可以在獲取到這個注解實例后調(diào)用這個value() 方法獲取值
可以不止一個方法,多一個方法线得,就可以多傳一個參數(shù)饶唤,如果有默認值,也可以不傳

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FindView{
    /**
     * id 注解贯钩,這里沒有默認值,不過可以自由添加,
     * 例如:public String tableName() default "className";
     * @return
     */
    int value();
}

從上面注解的定義來角雷,類似于接口祸穷,所以注解本身不具備解析和其他操作的功能,這里我們想要的是利用這個注解攜帶的value勺三,初始化這個注解所表示的成員變量雷滚,所以我們需要自己寫一個工具類,通過傳入的activity獲取注解吗坚,并利用反射初始化成員變量祈远。以下是詳細代碼:

public class ViewUtil {
    public static void viewInject(Activity activity){
        viewInjects(activity);
    }

    private static void viewInjects(Activity activity){
        Class<? extends Activity> clazz = activity.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for(Field field:fields){
            FindView viewFind = field.getAnnotation(FindView.class);
            if(viewFind!=null){
                int viewId = viewFind.value();
                View view = activity.findViewById(viewId);
                try {
                    field.setAccessible(true);
                    field.set(activity, view);

                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

最后是具體的使用方法

public class MainActivity extends AppCompatActivity {
       @FindView(R.id.btn)
    Button btn;
    @FindView(R.id.btn1)
    Button btn1;
    @FindView(R.id.btn2)
    Button btn2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ViewUtil.viewInject(this);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                btn.setText("Test2");
            }
        });
    }
}

以上是@Retention(RetentionPolicy.RUNTIME)運行時解讀的具體寫法。
優(yōu)點是可讀性強商源,寫起來簡單车份。
缺點便是常駐內(nèi)存,并利用反射進行初始化牡彻,耗費內(nèi)存

如何解決這個問題呢扫沼?其實我們可以利用apt,使用編譯時解讀或者類加載時解讀庄吼,后面的文章我會重點講到缎除,這里就不多啰嗦了。

So easy!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末总寻,一起剝皮案震驚了整個濱河市器罐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌渐行,老刑警劉巖技矮,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異殊轴,居然都是意外死亡衰倦,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門旁理,熙熙樓的掌柜王于貴愁眉苦臉地迎上來樊零,“玉大人,你說我怎么就攤上這事孽文∽そ螅” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵芋哭,是天一觀的道長沉衣。 經(jīng)常有香客問我,道長减牺,這世上最難降的妖魔是什么豌习? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任存谎,我火速辦了婚禮,結(jié)果婚禮上肥隆,老公的妹妹穿的比我還像新娘既荚。我一直安慰自己,他們只是感情好栋艳,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布恰聘。 她就那樣靜靜地躺著,像睡著了一般吸占。 火紅的嫁衣襯著肌膚如雪晴叨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天矾屯,我揣著相機與錄音兼蕊,去河邊找鬼。 笑死问拘,一個胖子當著我的面吹牛遍略,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播骤坐,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼绪杏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了纽绍?” 一聲冷哼從身側(cè)響起蕾久,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拌夏,沒想到半個月后僧著,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡障簿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年盹愚,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片站故。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡皆怕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出西篓,到底是詐尸還是另有隱情愈腾,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布岂津,位于F島的核電站虱黄,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏吮成。R本人自食惡果不足惜橱乱,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一辜梳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧仅醇,春花似錦冗美、人聲如沸魔种。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽节预。三九已至叶摄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間安拟,已是汗流浹背蛤吓。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留糠赦,地道東北人会傲。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像拙泽,于是被迫代替她去往敵國和親淌山。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 本文章涉及代碼已放到github上annotation-study 1.Annotation為何而來 What:A...
    zlcook閱讀 29,158評論 15 116
  • 內(nèi)容概要 Annotation的概念 Annotation的作用 Annotation的分類 系統(tǒng)內(nèi)置注解 元注解...
    DevinZhang閱讀 4,164評論 0 28
  • 一顾瞻、什么是注解泼疑? 注解對于開發(fā)人員來講既熟悉又陌生,熟悉是因為只要你是做開發(fā)荷荤,都會用到注解(常見的@Overrid...
    _Justin閱讀 1,353評論 0 10
  • 一輛Morgan +4停在了Brook Street 69號門口退渗,一位身著皮革駕車裝的紳士從車中走出,快步進入了S...
    時尚先生Esquire閱讀 472評論 0 0
  • 事與愿違之同工同酬法 同工同酬法不管它的用意多么善良蕴纳,但在實際效果上会油,它剝脫了那些競爭力比較弱的人跟競爭力強的人展...
    蒙山布衣閱讀 164評論 0 0