三分鐘秒懂注解
各位開發童鞋,注解這個東西我們肯定每天都能看見,也許有時候看的太多了到是會忽略注解這東西具體是如何工作的。今天在這里用最短的篇幅快速講解下注解的原理,對這塊記的不太清楚的同學也可以再次看看,下次有人詳細問這塊的話不至于一知半解。
元注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
@Documented
@Inherited
public @interface From {
int value() default 1;
boolean canBeNull() default false;
}
把注解講完這一個栗子就夠了,可以看到自定義注解里也會有注解存在,給自定義注解使用的注解就是元注解:
- @Rentention Rentention用來標記自定義注解的有效范圍,一般就三種:RetentionPolicy.SOURCE 只在源代碼中保留 一般都是用來增加代碼的理解性或者幫助代碼檢查之類的,比如我們的Override;RetentionPolicy.CLASS 默認的選擇,能把注解保留到編譯后的字節碼class文件中,僅僅到字節碼文件中,運行時是無法得到的;RetentionPolicy.RUNTIME,注解不僅 能保留到class字節碼文件中,還能在運行通過反射獲取到,一般我們真正用到的都是這種。(這個點在面試過程中有可能被問到,記性不好的趕緊收藏一下,下次要面試之前可以快速瀏覽一遍半個月都忘不了)。
- @Target 說明注解使用的地方,值很多,不一一細說了
- @Documented 使用了@Documented的可以在javadoc中找到
- @Interited 可繼承性的標識,使用了Interited表示注解里的內容可以被子類繼承,比如父類中某個成員使用了上述@From(value),From中的value能給子類使用到。
關鍵字和注解內容
- @interface 這個東西在聲明注解的時候必須得使用,用@interface就意味著這個東西已經繼承了java.lang.annotation.Annotation,也說明了它是一個注解。
然后就是注解里的內容了,上述From中定義了兩項內容,所以這個注解可以這么用:@From(1),或者是@From(value = 1,canBuNull = true)或者是@From(canBuNull = true),那么能不能寫成@From(true)呢。。當然不能,當括號里內容不以鍵值對形式出現的話默認是使用value的。
工作原理
最再說說注解的工作原理吧。也很簡單,一般我們自定義的RetentionPolicy.RUNTIME比較多,就說一下它的大概原理吧,其實可以把這種注解理解成一個可以接收參數的方法,只不過這個方法的處理邏輯是別人事先寫好的,使用了RetentionPolicy.RUNTIME的注解括號里提供的參數都是可以通過反射拿到,舉個很簡單的栗子,就拿下面來說:
From(R.id.tvLogin)
TextView tvLogin;
用這個From來接受一個id最后給tvLogin注入TextView的實例,我們在定義了這個@From注解后,再提供一個方法,在需要注入的時機調用(eg:OnCreate())
void onCreate(){
Injection.inject(this);
}
class Injection{
void inject(){
int id = getIDFromReflection();//通過反射獲得@From(id)中的id
TextView tv = getMemberFormReflection();//通過反射得到添加了@From注解的需要被注入的View
tv = (TextView)xxx.findViewById(id);
}
}
就這樣,通過From就輕松得省去了一大堆findViewById的方法,說到底,注解最大的好處就是讓代碼變得簡潔明了然后還能減少一些重復的機械勞動,解放雙手。
其實注解就那么點東西,很簡單的,平時如果使用的太多而而忽略了它的原理就有點不太靠譜了,我個人覺得做到理解了就行,很多內容全要記下來也是不可能的,只要明白了原理,太細節的地方用的時候再來查完全都不是問題了。
來自:https://dreamerhome.github.io/2016/08/02/annotaion/