本篇大部分来自网络。算是一个注解整合!
注解说明
注解分类
- 标示注解: 成员个数为0
- 单值注解: 成员个数为1
- 完整注解: 成员个数大于1
- 系统注解: 系统提供的注解
- 元注解: 为注解所注解
系统注解
@override
被修饰的方法必须为父类方法重写, 标示为该方法是方法重写
@Deprecated
被修饰的方法的方法名出现删除线, 标示为该方法已被废弃, 该修饰有继承性, 父类拥有所有子类都将被废弃.
@SuppressWarnings(可变参数)
解除编译器的警告, 提供多种参数
- deprecation 使用过时的方法或者类的警告
- unchecked 执行了未检查的转换时的警告
- failthrouth 当switch语句直接通往下一种情况,而没有break时的警告
- path 在类路径,源文件路径等中有不存在的路径时的警告
- serial 当在可序列化的类上缺少id
- finally 任何finally子句不能正常完成的警告
- all 关于以上所有警告的情况
- unused 关闭未被使用警告
@Repeatable
1.8加入的新注解,允许多次使用同一个注解
元注解
@Target(可变参数)
- ElementType.TYPE 用于描述类、接口(包括注解类型) 、枚举声明
- ElementType.FIELD 用于描述成员变量和枚举常量
- ElementType.METHOD 用于描述方法
- ElementType.PARAMETER 用于描述参数
- ElementType.CONSTRUCTOR 用于描述构造方法
- ElementType.LOCAL_VARIABLE 用于描述局部变量
- ElementType.ANNOTATION_TYPE 用于描述注解类型
- ElementType.PACKAGE 用于描述包
- ElementType.TYPE_PARAMETER 1.8加入的,用于描述类型参数
- ElementType.TYPE_USE 1.8加入的,用于描述类型的使用
Retention(可变参数)
- RetentionPolicy.SOURCE 注解只在源码中存在
- RetentionPolicy.CLASS 注解在源码和字节码中存在
- RetentionPolicy.RUNTIME 注解在源码、字节码和运行中都存在
@Documented
注解会在生成Doc文档时保留注解
@Inherited
规定注解被子类继承, 该注解只能修饰类, 且类必须被@Retention(RetentPoicy.Runtime)
修饰
自定义注解
自定义两个注解,注解1获取layoutId,注解2获取resId
获取layoutId
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
@LayoutRes int value() default View.NO_ID;
}
在Activity类最外层加入
@Test(R.layout.activity_main)
public class MainActivity
然后我们获取注解上的id,调用setContentView
方法将id设置到Activity上面就可以了
具体调用获取如下
Class<?> clazz = this.getClass();
if (clazz.getAnnotations() != null) {
if (clazz.isAnnotationPresent(Test.class)) {
Test test = clazz.getAnnotation(Test.class);
Log.e("-s-", "id = "+test.value());
if (test.value() != -1) {
setContentView(test.value());
}
}
}
流程为
1. 获取class类全部注解
2. 遍历注解是否为对应的注解
3. 获取注解的值
4. 设置id
获取resId
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface Test2 {
@IdRes int value() default View.NO_ID;
}
在参数中设置
@Test2(R.id.btn)
Button btn;
我们可以和上面一样获取注解,然后获取到id,在设置给Activity就可以了。
代码如下
Class<?> clazz = this.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.getAnnotations() != null) {
if (field.isAnnotationPresent(Test2.class)) {
try {
Test2 test2 = field.getAnnotation(Test2.class);
//允许修改反射属性
field.setAccessible(true);
field.set(this, this.findViewById(test2.value()));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
流程为
1. 获取class全部内部参数注解
2. 遍历注解判断是否相同
3. 获取注解对象参数打开反射
4. 将对应的注解id和对象参数绑定