在使用许多第三方框架的时候,查阅源码如ButterKnife等。发现许多注解的使用,顿时觉得注解都玩不溜怎么称霸武林。当然无论Java还是AndroidSDK中都有大量注解的使用,以前总是走马观花,印象中知道注解代表的意思,但开口总是说不清道不明,唯有总结方得始终。

注解是附加在代码中的一些信息,可以帮助一些代码分析工具如Lint分析代码,辅助开发者改善代码,对于开发者来说有个提示、警告的作用。但注解不会改变代码逻辑。在此总结了几个Android开发常见的注解的解释,以及对元注解的基本认识。


常见的几个注解

1@TargetApi

2@RequiresApi

3@suppressLint

4@SuppressWarnings


@TargetApi(Build.VERSION_CODES.M)@TargetApi(23)

Lint会按照API版本M以上扫描代码,而不是project中指定的minSDKVersion,可以使得高版本Api在低版本SDKLint不报错。如果只加这个注解,表明这段代码只能在23及以上的系统上运行,如果你非要在23以下的系统上运行,那该警告的已经警告了,你只是忽略了警告,但运行时该错还是错。


@RequiresApi(api = Build.VERSION_CODES.M)

表示注解目标只能够在指定的版本API及以上运行,消除高版本Api在低版本SDK上的报错,作用上和TargetApi相同,只是在词面上更清楚表达了这是一个建议,而不仅仅是为了消除高版本Api在低版本SDK上的报错。从官方的表述可以看出更推荐使用RequiresApi替换TargetApi


@SuppressLint("NewApi")

最直接暴力屏蔽指定名称的报错,这里的NewApi对应的具体错误名称是:Calling new methods on older versions。这里的NewApi只是一个缩写名称。相比于@TargetApi指定了版本号,SuppressLint是一律屏蔽,所以一般不建议使用。当然还可以指定任何其他Lint定义好的错误名称。在settings中查找Inspections可以找到预先定义好的所有ErrorWarning。对于多个错误,使用逗号隔开。

XML中类似的做法有:

tools:ignore="ScrollViewCount,UselessParent"忽略XML中的两个警告。


@SuppressWarnings("NumericOverflow")

屏蔽NumericOverflow警告,如:int a = 1 / 0;

一般的语句注解方式suppress for statement 

    @SuppressWarnings("NumericOverflow")

     int a = 10 / 0;

注释注解方式statement for statement with comment

     //noinspection NumericOverflow(以前总是看到这样的注释,但并不知道也是注解)

     int a = 10 / 0;

当然,这些注解可以使用在许多地方如:classmethodstatement,分别对应由大到小不同的作用域类、方法、语句,当然作用域范围越大,那么性能损耗自然越大。


Annotation不影响代码逻辑

这些注解的作用只是去除Lint的错误警告,并不能影响任何的代码逻辑。

所以必须在代码中添加相应的兼容性判断代码,如:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

      color = getColor(R.color.colorAccent);

}

当然,当你添加完上述兼容代码后,警告也就消失了。


元注解(注解的注解)

常见的元注解:

1@Documented

2@Inherited

3@Retention

4@Target

分析SuppressLint的定义:

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})

@Retention(RetentionPolicy.CLASS)

public @interface SuppressLint {

 value();

}

@Target定义作用目标

其中@Target指定了SuppressLint的作用目标,具体TYPEFIELD等代表什么,可以在java.lang.annotation.ElementType里面找到。

例如:TYPE表示

/** Class, interface (including annotation type), or enum declaration */

即包含了类、接口(包括注解)、枚举类型。

例如:@Override注解

@Target(ElementType.METHOD)  重写,只能作用于方法

@Retention(RetentionPolicy.SOURCE)  只存在于编码阶段,编译阶段就失效了

public @interface Override {}


@Retention定义保留策略

1PetentionPolicy.SOURCE 仅保留在源码阶段,编译阶段就失效

2PetentionPolicy.CLASS默认策略,会保留到编译出字节码阶段,运行时失效

3PetentionPolicy.RUNTIME 保留到VM的运行时阶段,可通过反射获得


@Documented   注解将被写入javadoc

@Inherited   子类可以继承父类中的该注解

@Repeatable   找不到例子,有待理解

@Native   尚处于Preview状态,表示常量有可能被本地代码引用