章节:
1.概念
2.使用场景
3.常见的注解
4.自定义注解
5.注解缺点
1.概念
注解:起到标注、注释的作用。本身没有意义,需要结合反射、插住、动态代理等技术使用。
public @interface Test {
}
元注解(meta-annotation):就是注解的注解。 例如: 1.@Documented :注解是否包含在javaDoc中。 2.@Retention(RetentionPolicy.SOURCE) //保留级别,什么时候使用该注解。 3.@Target注解用在什么地方。 4.@Inherited 是否允许子类继承该注解。 ...
@Retention(RetentionPolicy.SOURCE) //保留级别
@Target({ElementType.Type}) //作用在哪里,是一个数组:可以在类上、方法、字段等。
@interface Test {
}
Retention / Target 等就是元注解
RetentionPolicy.SOURCE:生成class文件的时候,不带上这个注解。
RetentionPolicy.CLASS; java 生成.class文件保留,但会被jvm抛弃。android 打包dex的时候,不带上这个注解。
RetentionPolicy.RUNTIME;被虚拟机解析识别。
SOURCE < CLASS < RUNTIME。后者包含了前者。
2.使用场景
RUNTIME :会被虚拟机识别。可以结合反射使用。
CLASS:字节码插桩(在class文件写代码)
SOURCE: IntDef
1.APT 在编译时期生成java类。例如在Glide里面会生成一些类。
扩展一下:APT执行时期:
原理:apt技术其实就是javac的一种,算是一个小插件。
2.IntDef 达到限制参数的取值范围。替换掉枚举的一种方式。 扩展: 枚举在编译后,会把枚举里面的每个值都编译成为对象,更加耗内存。
@Retention(RetentionPolicy.SOURCE)
@IntDef({
Corner.TOP_LEFT, Corner.TOP_RIGHT,
Corner.BOTTOM_LEFT, Corner.BOTTOM_RIGHT
})
public @interface Corner {
int TOP_LEFT =0;
int TOP_RIGHT =1;
int BOTTOM_RIGHT =2;
int BOTTOM_LEFT =3;
}
##3.常见的注解 常见的注解:例如:@Override 、@NonNull 、@StringRes等。
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.METHOD})
public @interface Override {
}
@Documented
@Retention(CLASS)
@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE, ANNOTATION_TYPE, PACKAGE})
public @interface NonNull {
}
##4.自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Test {
Object name();//错误、注意一下,返回值只能是Enum、八种基本类型、String、Class、annotation和这12种类型的数组。
String name();
}
注意一下,注解的返回值只能是Enum、八种基本类型、String、Class、annotation和这12种类型的数组。
//定义
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Test {
String name() default "default_name";//默认值
String value() default "default_value";
}
//使用
public class User {
@Test(name = "name1") //这里注意一下。如果是方法不是value、需要用方法名 = '××'
private String name;
@Test("name2")
private String name_2;
}
//利用反射取值
User user = new User();
Field[] declaredFields = user.getClass().getDeclaredFields();
for (Field declaredField : declaredFields) {
if (declaredField.isAnnotationPresent(Test.class)) {
Test annotation = declaredField.getAnnotation(Test.class);
String name = annotation.name();
String value = annotation.value();
Log.e("TAG", "value =" + value + ",name=" + name);
}
}
输出:
value =name2,name=default_name
value =default_value,name=name1
##5.注解缺点 1.分散在java各个文件中。不好管理。