1.注解是给编译器处理;(需要有特定的代码处理)
2.注解上也可以打注解,这种特殊的注解为元注解;注解里面可以加参数;
常见的注解:
@Override
@Deprecated
自定义的注解:
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的枚举类
source级别:注释将被编译器丢弃。
class级别:注释将由编译器记录在类文件中,但不需要在运行时由 VM 保留。这是默认行为。
RUNTIME级别:注释将由编译器记录在类文件中,并在运行时由 VM 保留,因此可以反射性地读取它们。(这点非常重要)
例如注解@Override,他的元注解就是@Target(ElementType.Method)表示@Override只能使用在方法上面;
@Retention(RetentionPolicy.Source)表示重写的标注只会在被编译之前用于一些检查,不会被带入到类文件,也不会带入到jvm中;