温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Annotation注解及元注解

发布时间:2020-05-06 21:44:04 来源:网络 阅读:7615 作者:一剑围城 栏目:开发技术

在使用许多第三方框架的时候,查阅源码如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状态,表示常量有可能被本地代码引用


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI