今天看了一些注解的源码,发现这三个注解有点搞不清楚,于是想着写篇博客,加深一下印象,如果有幸能够帮到别人,那再好不过了。
@Retention
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE, //(会被编译器丢弃)
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*/
CLASS, //(注解将会被保留在Class文件中,但在运行时并不会被VM保留。没有用Retention注解的注解,都会采用 CLASS 策略。)
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME // (保留至运行时。所以可以通过反射去获取注解信息。)
}
接着来个例子瞅一瞅。
@Retention(RetentionPolicy.SOURCE)
public @interface SourceLevel { }
@Retention(RetentionPolicy.RUNTIME)
public @interface RuntimeLevel { }
@Retention(RetentionPolicy.CLASS)
public @interface ClassLevel { }
public class Test_Annotation {
@SourceLevel
public void sourceLevel() {}
@ClassLevel
public void classLevel() {}
@RuntimeLevel
public void runtimeLevel() {}
public static void main(String[] args) {
}
}
Javap -verbose Test_Annotation 得到
Compiled from "Test_Annotation.java"
public class data_test.Test_Annotation
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Class #2 // data_test/Test_Annotation
#2 = Utf8 data_test/Test_Annotation
#3 = Class #4 // java/lang/Object
#4 = Utf8 java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Utf8 Code
#8 = Methodref #3.#9 // java/lang/Object."<init>":()V
#9 = NameAndType #5:#6 // "<init>":()V
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Ldata_test/Test_Annotation;
#14 = Utf8 sourceLevel
#15 = Utf8 classLevel
#16 = Utf8 RuntimeInvisibleAnnotations
#17 = Utf8 Ldata_test/ClassLevel;
#18 = Utf8 runtimeLevel
#19 = Utf8 RuntimeVisibleAnnotations
#20 = Utf8 Ldata_test/RuntimeLevel;
#21 = Utf8 main
#22 = Utf8 ([Ljava/lang/String;)V
#23 = Utf8 args
#24 = Utf8 [Ljava/lang/String;
#25 = Utf8 SourceFile
#26 = Utf8 Test_Annotation.java
{
**public data_test.Test_Annotation();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 9: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Ldata_test/Test_Annotation;
public void sourceLevel();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=0, locals=1, args_size=1
0: return
LineNumberTable:
line 12: 0
LocalVariableTable:
Start Length Slot Name Signature
0 1 0 this Ldata_test/Test_Annotation;
public void classLevel();
descriptor: ()V
flags: ACC_PUBLIC
RuntimeInvisibleAnnotations:
0: #17()
Code:
stack=0, locals=1, args_size=1
0: return
LineNumberTable:
line 14: 0
LocalVariableTable:
Start Length Slot Name Signature
0 1 0 this Ldata_test/Test_Annotation;
public void runtimeLevel();
descriptor: ()V
flags: ACC_PUBLIC
RuntimeVisibleAnnotations:
0: #20()
Code:
stack=0, locals=1, args_size=1
0: return
LineNumberTable:
line 16: 0
LocalVariableTable:
Start Length Slot Name Signature
0 1 0 this Ldata_test/Test_Annotation;**
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=0, locals=1, args_size=1
0: return
LineNumberTable:
line 20: 0
LocalVariableTable:
Start Length Slot Name Signature
0 1 0 args [Ljava/lang/String;
}
SourceFile: "Test_Annotation.java"
编译器并没有记录下sourceLevel方法的注解信息 ,
使用 RuntimeInvisibleAnnotations属性 记录 classLevel 的注解信息
使用 RuntimeVisibleAnnotations属性 记录 runtimeLevel的注解信息
@Retention 表示 该注解类的生命周期
暂时先了解到这,以后再用到再接着记录。
@Target
@Target 表示 该注解类的声明位置。
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
}
@Document
Documented注解表明这个注释是由 javadoc记录的,并且在默认情况下也有类似的记录工具。 如果一个类型声明被注释了文档化,它的注释成为公共API的一部分。
参考:https://blog.csdn.net/asdgbc/article/details/70196749
https://blog.csdn.net/cb905259982/article/details/73161948?utm_source=blogxgwz0