一. 基本概念
元注解(meta annotation):用于修饰其他注解的注解
常用元注解:
@Documented:指示使用此注解的内容会生成到Java Doc中
@Retention:注解的生命周期
SOURCE : 只存在Java源文件,不会被编译
CLASS:会被编译到字节码文件,但不会运行(默认值)
RUNTIME:运行期间,可在运行期间通过反射获取此注解
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,
/**
* 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
}
@Target:限定注解能被应用在那些Java类型上
TYPE:类,接口,枚举
FIELD:变量
METHOD:方法
PARAMETER:方法的入参
CONSTRUCTOR:构造器
LOCAL_VARIABLE:局部变量
ANNOTATION_TYPE:注解
PACKAGE:包(没见过)
TYPE_PARAMETER:类型参数,表示这个注解可以用在 Type的声明式前,jdk1.8引入。
TYPE_USE:类型的注解,表示这个注解可以用在所有使用Type的地方(如:泛型,类型转换等),jdk1.8引入。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}
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
}
@Inherited:子类是否可继承此注解
@Repeatable:定义此注解是否可以在一处重复定义
二. 自定义注解实现
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Validate {
/**
* 最大值
*
* @return
*/
int max();
/**
* 最小值
*
* @return
*/
int min();
}
public class User {
@Validate(min = 1, max = 50)
public int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public static void main(String[] args) {
User user = new User();
user.setAge(-5);
check(user);
user.setAge(15);
check(user);
}
//测试结果:
三. 字节码
Classfile /home/yuhan/Documents/workspace/Roc/target/classes/com/roc/spring/anonation/Validate.class
Last modified Nov 5, 2021; size 467 bytes
MD5 checksum 1e4af246079397127c737737ea76add1
Compiled from "Validate.java"
// 注解就是一个继承了Annotation的接口类
public interface com.roc.spring.anonation.Validate extends java.lang.annotation.Annotation
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
Constant pool:
#1 = Class #18 // com/roc/spring/anonation/Validate
#2 = Class #19 // java/lang/Object
#3 = Class #20 // java/lang/annotation/Annotation
#4 = Utf8 max
#5 = Utf8 ()I
#6 = Utf8 min
#7 = Utf8 SourceFile
#8 = Utf8 Validate.java
#9 = Utf8 RuntimeVisibleAnnotations
#10 = Utf8 Ljava/lang/annotation/Target;
#11 = Utf8 value
#12 = Utf8 Ljava/lang/annotation/ElementType;
#13 = Utf8 FIELD
#14 = Utf8 Ljava/lang/annotation/Retention;
#15 = Utf8 Ljava/lang/annotation/RetentionPolicy;
#16 = Utf8 RUNTIME
#17 = Utf8 Ljava/lang/annotation/Documented;
#18 = Utf8 com/roc/spring/anonation/Validate
#19 = Utf8 java/lang/Object
#20 = Utf8 java/lang/annotation/Annotation
{
public abstract int max();
descriptor: ()I
flags: ACC_PUBLIC, ACC_ABSTRACT
public abstract int min();
descriptor: ()I
flags: ACC_PUBLIC, ACC_ABSTRACT
}
SourceFile: "Validate.java"
RuntimeVisibleAnnotations:
// 常量池里找10,Target
0: #10(#11=[e#12.#13])
// 14:Retention
1: #14(#11=e#15.#16)
//17:Documented
2: #17()
注解就是一个继承了Annotation的接口类,内部方法就和接口一致
RuntimeVisibleAnnotations:就是展示它带有的元注解列表
public class com.roc.spring.anonation.User
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #4.#26 // java/lang/Object."<init>":()V
#2 = Fieldref #3.#27 // com/roc/spring/anonation/User.age:I
#3 = Class #28 // com/roc/spring/anonation/User
#4 = Class #29 // java/lang/Object
#5 = Utf8 age
#6 = Utf8 I
#7 = Utf8 RuntimeVisibleAnnotations
#8 = Utf8 Lcom/roc/spring/anonation/Validate;
#9 = Utf8 min
#10 = Integer 1
#11 = Utf8 max
#12 = Integer 50
#13 = Utf8 <init>
#14 = Utf8 ()V
#15 = Utf8 Code
#16 = Utf8 LineNumberTable
#17 = Utf8 LocalVariableTable
#18 = Utf8 this
#19 = Utf8 Lcom/roc/spring/anonation/User;
#20 = Utf8 getAge
#21 = Utf8 ()I
#22 = Utf8 setAge
#23 = Utf8 (I)V
#24 = Utf8 SourceFile
#25 = Utf8 User.java
#26 = NameAndType #13:#14 // "<init>":()V
#27 = NameAndType #5:#6 // age:I
#28 = Utf8 com/roc/spring/anonation/User
#29 = Utf8 java/lang/Object
{
public int age;
descriptor: I
flags: ACC_PUBLIC
RuntimeVisibleAnnotations:
0: #8(#9=I#10,#11=I#12)
使用了validate注解的age,带了RuntimeVisibleAnnotations,#8(#9=I#10,#11=I#12)
#8:注解类,Lcom/roc/spring/anonation/Validate
#9:注解的min方法,#10表示设置的是10
#11:注解的max方法,#12表示设置的是50