1.注解是给编译器处理;(需要有特定的代码处理)

2.注解上也可以打注解,这种特殊的注解为元注解;注解里面可以加参数;

常见的注解:

@Override

alt

@Deprecated

alt

自定义的注解:

package com.ydlclass;

public @interface Annotation {
    //一个注解存在,就一定存在解析这个注解的代码存在,
    String name();//类似于抽象方法,当我们使用的时候有点类似于匿名内部类;
    //需要把这个方法的返回值写在注解的括号里;

    int age() default 16;//注解中"属性"可以使用关键字default来制定,使用注解时可以不用给此属性赋值

    //如果属性不需要指定名字,将方法名写成value,但是制定多个属性时value就不能省略;


    //
}

3.注解和元注解的本质

为了能看到注解的本质,可以在常见的方法前使用注解,编译后查看注解的二进制字节码,使用javap -v /注解的文件;

PS D:\code\MyReviewer\out\production\api\com\ydlclass> javap -v .\Annotation.class
Classfile /D:/code/MyReviewer/out/production/api/com/ydlclass/Annotation.class
  Last modified 2022-6-8; size 245 bytes
  MD5 checksum e7b34ebd98b2fd95d76280297ff72c8b
  Compiled from "Annotation.java"
public interface com.ydlclass.Annotation extends java.lang.annotation.Annotation
//此处可以发现注解的本质是一个继承自java.lang下面的Annotation接口
  minor version: 0
  major version: 55
  flags: ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION//标识里面标志了他是一个抽象方法
Constant pool:
   #1 = Class              #12            // com/ydlclass/Annotation
   #2 = Class              #13            // java/lang/Object
   #3 = Class              #14            // java/lang/annotation/Annotation
   #4 = Utf8               name
   #5 = Utf8               ()Ljava/lang/String;
   #6 = Utf8               age
   #7 = Utf8               ()I
   #8 = Utf8               AnnotationDefault
   #9 = Integer            16
  #10 = Utf8               SourceFile
  #11 = Utf8               Annotation.java
  #12 = Utf8               com/ydlclass/Annotation
  #13 = Utf8               java/lang/Object
  #14 = Utf8               java/lang/annotation/Annotation
{
  public abstract java.lang.String name();
    descriptor: ()Ljava/lang/String;
    flags: ACC_PUBLIC, ACC_ABSTRACT

  public abstract int age();
    descriptor: ()I
    flags: ACC_PUBLIC, ACC_ABSTRACT
    AnnotationDefault:
      default_value: I#9}
SourceFile: "Annotation.java"
PS D:\code\MyReviewer\out\production\api\com\ydlclass>
//同样有自己的常量池,抽象方法,

4.一般需要给每个注解加上元注解,其中元注解@Target元注解修饰注解之后,可以限制我们自定义的注解用于,方法,字段,类,接口其中的一种或者几种;

Retention注解,以及RetentionPolicy的枚举类

alt

alt

source级别:注释将被编译器丢弃。

class级别:注释将由编译器记录在类文件中,但不需要在运行时由 VM 保留。这是默认行为。

RUNTIME级别:注释将由编译器记录在类文件中,并在运行时由 VM 保留,因此可以反射性地读取它们。(这点非常重要)

例如注解@Override,他的元注解就是@Target(ElementType.Method)表示@Override只能使用在方法上面;

@Retention(RetentionPolicy.Source)表示重写的标注只会在被编译之前用于一些检查,不会被带入到类文件,也不会带入到jvm中;