1.简介
Java注解是一系列元数据,它提供数据用来解释程序代码,但是注解并非是所解释的代码本身的一部分。 注解对于代码的运行效果没有直接影响。
个人理解:注解就是给代码加上标记,这个标记可以在编译时、运行时获取到,从而可以让我们对
打标记的代码在编译或者运行时进行处理。
注解本身没有任何意义,单独的注解就是一种注释,它需要结合其它如反射、插桩等技术才有意义
2.定义注解
注解和接口的定义一样,使用interface关键词,不过需要在关键词前加上@
public @interface Chxip {
}
注解有两个比较常用的元注解(可以理解为属性) 元注解:可以作用在注解上的注解
-
Target:标识此注解可以修饰的对象范围,比如方法,属性,类等
值 | 作用 |
---|
ElementType.TYPE | 接口、类、枚举、注解 | ElementType.FIELD | 字段、枚举的常量 | ElementType.METHOD | 方法 | ElementType.PARAMETER | 方法参数 | ElementType.CONSTRUCTOR | 构造函数 | ElementType.LOCAL_VARIABLE | 局部变量 | ElementType.ANNOTATION_TYPE | 注解(作用在注解上,就是元注解) | ElementType.PACKAGE | 包 |
-
Retention:保留级别
值 | 作用 |
---|
RetentionPolicy.SOURCE | 保留在源码中,会被编译器忽略 使用APT注解处理程序可以用于生成额外的辅助类,语法检查 | RetentionPolicy.CLASS | 在编译时会保留,但是JAVA虚拟机会忽略 在编译出Class后,通过修改Class数据以实现修改代码逻辑 | RetentionPolicy.RUNTIME | JVM保留,运行时可以使用它 在程序运行期间,通过反射动态获取注解与其元素,从而完成不同的逻辑判定 |
使用方式,在自己定义的注解上加上这两个元注解就好啦
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface Chxip {
}
3.注解传参
直接在注解中定义对应的参数名,在使用注解的时候传进来,可以设置默认值,设置了默认值后,这个参数可以不传
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface Chxip {
String value() defalut "";
}
使用
@Chxip("aaaa")
public void Test(){
}
有多个参数怎么处理呢?
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface Chxip {
String value();
int id();
}
使用
@Chxip(value = "aaaa",id = 1)
public void Test(){
}
注意:value这个参数是默认的,在传值的时候可以不写对应的key,其它名称的参数必须以key-value的形式,如果有其它参数,value也需要以key-value的格式传入
4. 语法检查
-
Android中提供了很多注解来帮助我们进行代码规范检查
注解 | 作用 |
---|
@NonNull | 参数不能为空 | @UiThread | 标识方法在主线程运行 | @AnimatorRes | 动画资源 | @ColorRes | 颜色资源 | @ColorInt | 颜色资源 | @DimenRes | 尺寸资源 | @DrawableRes | drawable资源 | @LayoutRes | 布局xml资源 | @StringRes | String资源 |
-
自定义注解检查
- @IntDef 定义Int类型的注解检查
- @StringDef 定义String类型的注解检查
在开发中,我们要限定某个方法只能用那些值,我们一般都使用枚举类型来处理,但是枚举是比较耗费内存的,我们一般使用静态常量来处理,但是又没有办法提示调用者应该使用哪些值,这个时候我们可以自定义一些代码规范提示,来提示调用者我们的方法需要什么类型的数据; public class Test {
public static final int MAN = 0 ;
public static final int WOMAN = 1 ;
@IntDef({MAN,WOMAN})
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.SOURCE)
@interface Sex{
}
public static void setSex(@Sex int sex){
}
}
我们在调用此方法时 可以看到,如果没有传设置的值,编译器会提示我们应该传哪些值,但是这个只是提示我们,运行不受影响
5. Kotlin注解
kotlin中的注解和Java的基本一致,详细可以参考 https://juejin.cn/post/6844903829868134407
|