概念
注解本身没有任何意义,单独的注解就是一种注释,需要结合反射、插桩等技术才有意义。
Java 注解(annotation)又称 Java 标注,是 JDK 1.5 引入的一种注释机制,是元数据的一种形式,提供有关于程序但不属于程序本身的数据,注解对它们注解的代码的操作没有直接影响
定义
package Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface CustomAnnotation {
String value();
}
使用:
当只声明了 value 时。
@CustomAnnotation("无需key value")
public class AnnotationTest {
}
当同时声明了 value 和 其他时
@CustomAnnotation(value = "无需key value",code = 10)
public class AnnotationTest {
}
其中 @Target
和 @Retention
是元注解,是最常用的两个。
@Target 用来限定作用域, 限制此注解是作用在类还是参数还是方法等
public enum ElementType {
/** Class, interface (including annotation type), enum, or record
* 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,
//类型参数声明,JavaSE8引进,可以应用于类的泛型声明之处
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
//JavaSE8引进,此类型包括类型声明和类型参数声明,是为了方便设计者进行类型检查,例如,如果使用@Target(ElementType.TYPE_USE)对@NonNull进行标记,则类型检查器可以将@NonNull class C {...} C类的所有变量都视为非null
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE,
/**
* Module declaration.
*
* @since 9
*/
MODULE,
/**
* {@preview Associated with records, a preview feature of the Java language.
*
* This constant is associated with <i>records</i>, a preview
* feature of the Java language. Programs can only use this
* constant when preview features are enabled. Preview features
* may be removed in a future release, or upgraded to permanent
* features of the Java language.}
*
* Record component
*
* @jls 8.10.3 Record Members
* @jls 9.7.4 Where Annotations May Appear
*
* @since 14
*/
@jdk.internal.PreviewFeature(feature=jdk.internal.PreviewFeature.Feature.RECORDS,
essentialAPI=true)
RECORD_COMPONENT;
}
@Target 可以指定多个。
注意:如果一个注解没有指定@Target注解,则此注解可以用于除了TYPE_PARAMETER和TYPE_USE以外的任何地方。
@Retention
public enum RetentionPolicy {
/**
标记的注解仅保留在源级别中,并被编译器忽略
* Annotations are to be discarded by the compiler.
*/
SOURCE,
/**
标记的注解在编译时由编译器保留,但 Java 虚拟机会忽略
* 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,
/**
标记的注解由 JVM 保留,因此运行时环境可以使用它
* 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
}
SOUCE < CLASS < RUNTIME
CLASS 包含了 SOUCE,RUNTIME 包含了 SOUCE、CLASS。
应用场景
APT: Annotation Processor Tools 源码级别的注解。
字节码增强:class 级别。
反射:运行时。
网友评论