Java 注解(Annotation)又称 Java 标注,是 JDK1.5 引入的一种注释机制。是元数据的一种形式,提供有关于程序但不属于程序本身的数据。注解对它们注解的代码的操作没有直接影响。
注解本身没有任何意义,单独的注解就是一种注释,他需要结合其他如反射、插桩等技术才有意义。
@Target({
ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface Puppy {
int value();
String id();
}
元注解:注解上的注解
指示注解是作用在什么上面 ,
上面代码Puppy是只能作用在类和方法上面,没写的话可以作用在任何上面 (包名 类 方法 成员属性 方法参数等等)
ElementType枚举常量的含义:
注解中比较重要的,注解本身是没有任何意义的,它结合到到了其他的技术才有了更加丰富的运行场景。
保留级别一共有三种:
SOURCE: 标记的注解仅保留在源级别中,并被编译器忽略。
CLASS: 标记的注解在编译时由编译器保留,但 Java 虚拟机(JVM)会忽略。
RUNTIME: 标记的注解由 JVM 保留,因此运行时环境可以使用它(结合反射技术)。
(1)保留到源码级别:
APT:Annotation Processor Tools 注解处理器
javac帮我们调用注解处理程序
.java -----> javac ----> .class
采集到所有的注解信息-----> 把注解信息包装成一个节点 Element -----> javac调用注解处理程序
帮我们自动生成额外的辅助类(APT技术应用:ARouter Butterknife)
IntDef 提供元注解,语法检查:
public static void setDrawable(@DrawableRes int id){
}
public static void main(String[] args){
setDrawable(R.drawable.ic_launcher_background);
}
public class Test {
private static WeekDay mCurrentDay;
enum WeekDay {
SUNDAY,MONDAY
}
public static void setmCurrentDay(WeekDay currentDay){
mCurrentDay = currentDay;}
public static void main(String[] args){
setmCurrentDay(WeekDay.SUNDAY);
}
}
一个对象占用12个对象头+成员+8字节对齐,上述枚举用法光对象头就占用2个字节,枚举类型 占用内存。
public class Test {
@WeekDay2
private static int mCurrentDay;
private static final int SUNDAY = 0;
private static final int MONDAY = 1;
@IntDef({
SUNDAY,MONDAY})
@Target({
ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.SOURCE) //IDE实现的,IDE插件实现的
@interface WeekDay2{
}
public static void setmCurrentDay(@WeekDay2 int currentDay){
mCurrentDay = currentDay;}
public static void main(String[] args){
setmCurrentDay(SUNDAY);
}
}
注解处理器:
@SupportedAnnotationTypes("com.example.test.Puppy")
public class PuppyProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
Messager m = processingEnv.getMessager();
m.printMessage(Diagnostic.Kind.NOTE, "-----------------------------puppy");
return false;
}
}
Task :app:compileDebugJavaWithJavac 在编译时进行
(2)保留到字节码级别:
字节码增强: 在字节码当中写代码
.class->格式 数据按照特定的方式记录与排列
(3)保留到运行时级别: 反射