Android定義了很多有用的註解,可供我們使用,方便編程減少潛在錯誤的發生。
1 @Override @ NonNull @Nullable
Android 中最常見的就是@Override,繼承基類,重寫函數時不加@Override不會報錯,加上@Override編譯期會幫我們檢查重寫是否合法,如果參數,或者類型的不合法會給警告。
@NonNull 告訴編譯器,參數非空,可以避免函數內部參數null判斷,也會避免很多錯誤。
@Nullable 告訴編譯器 參數可以爲null。
2 @ IntDef,@StringDef註解
@IntDef和@StringDef註解可以很好的對函數參數進行限定。
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.ANNOTATION_TYPE})
public @interface StringDef {
String[] value() default {};
}
如果一個類,有三個類型,通常的做法可以直接用String或者int常量標識,或者用Enum,或者用註解,String或int只能限定類型,無法阻止用戶輸入,Enum比較耗費內存,註解是個不錯的選擇。
例如:
public class Demo1 {
public static final String type1 = "type1";
public static final String type2 = "type2";
public static final String type3 = "type3";
enum TypeEnum {
TYPE1("type1"),
TYPE2("type2"),
TYPE3("type3");
private String type;
TypeEnum(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
@StringDef({type1, type2, type3})
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.FIELD,ElementType.PARAMETER})
@interface TypeAnn{ }
public void test2(String type){ }
public void test3(TypeEnum type){ }
public void test4(@TypeAnn String type){ }
public void test5(){
test2("sldjfls");
test3(TypeEnum.TYPE1);
test3("sdlfjs");
test4("sldjfs");
test4(type1);
}
@StringDef({"a1", "a2", "a3"})
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.FIELD,ElementType.PARAMETER})
@interface StringAnn{ }
public void test5(@StringAnn String name){
}
public void test6() {
test5("asldjfls");
test5("a1");
}
}
@IntDef 用法類似:
除了@IntDef和@StringDef註解類似的還有@LongDef,它們都只能用於註解
3 @IntRange,@LongRange
@Retention(SOURCE)
@Target({METHOD,PARAMETER,FIELD,LOCAL_VARIABLE,ANNOTATION_TYPE})
public @interface IntRange {
/** Smallest value, inclusive */
long from() default Long.MIN_VALUE;
/** Largest value, inclusive */
long to() default Long.MAX_VALUE;
}
從源碼可以看到,IntRange可以應用的範圍比較廣,METHOD,PARAMETER,FIELD,LOCAL_VARIABLE,ANNOTATION_TYPE。
可以應用於方法(返回值),方法參數,字段,局部變量,註解類型,用的比較多的還是方法的參數上,或者返回值上。
@Size
定義長度大小,例如函數參數的長度。
@Retention(SOURCE)
@Target({PARAMETER,LOCAL_VARIABLE,METHOD,FIELD})
public @interface Size {
/** An exact size (or -1 if not specified) */
long value() default -1;
/** A minimum size, inclusive */
long min() default Long.MIN_VALUE;
/** A maximum size, inclusive */
long max() default Long.MAX_VALUE;
/** The size must be a multiple of this factor */
long multiple() default 1;
}
4 資源類相關
@AnimatorRes,@AnimRes,@DimenRes,@DrawableRes,@FontRes,@IdRes,@InterpolatorRes,@LayoutRes,@MenuRes
@PluralsRes,@RawRes,@StringRes,@StyleableRes,@StyleRes,@TransitionRes,@XmlRes。
@ArrayRes,@BoolRes,@IntegerRes。
@ColorRes,@ColorLong,@ColorInt。
資源註解可以防止在使用資源時,傳遞錯誤資源類型。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="intid">22</integer>
<item name="intid2" type="integer">22</item>
<array name="array1">
<item > 11</item>
<item > 12</item>
<item > 13</item>
<item > 14</item>
</array>
<item name="string" type="string">sldjfsdfl</item>
<item name="id2" type="id"/>
</resources>
5 其他
@RequiresApi ,@RequiresFeature,@RequiresPermission,@RestrictTo,@UiThread,@VisibleForTesting,@WorkerThread,
@MainThread,@Keep,@GuardedBy,@CallSuper。
@RequiresApi 需要的api版本
@RequiresFeature 需要的feature,AndroidManifest.xml中設置
@RequiresPermission 需要的權限
@Keep 代碼混淆,不混淆
@CallSuper註解主要是用來強調在覆蓋父類方法的時候,需要實現父類的方法,及時調用對應的super.**方法
@RestrictTo 註解的對象只接受一個特定範圍的值,值範圍是一個枚舉
@GuardedBy用來代替鎖,表示某變量只能在線程持有鎖時被某些線程訪問
@UiThread,MainThread,WorkerThread標識類中方法在哪個 工作。