1.简介
(1).概念
为程序元素(字段、方法、类、包)设置额外信息,然后在编译或者运行时使用。

(2).功能

  • 作为特定的标记,用于告诉编译器一些信息:@Override
  • 编译时动态处理,动态生成代码:@Dada
  • 运行时动态处理,作为额外信息的载体:@Controller @Service @Repository

2.元注解(注解上的注解)
(1).@Target
定义注解的使用范围

  • ANNOTATION_TYPE:注解
  • PACKAGE:包
  • TYPE:类、接口、枚举
  • METHOD:方法
  • CONSTRUCTOR:构造方法
  • FIELD:属性
  • PARAMETER:参数
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
}

(2).@Retention
定义注解的生命周期

  • SOURCE:只在源码中存在,编译后的.class文件中就不存在了
  • CLASS:存在于源码和.class文件中,如JDK自带的注解
  • 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
}

(3).@Documented
生成Javadoc时会包含的注解

(4).@Inherited
允许子类继承,子类只继承类上的注解

3.自定义注解
(1).定义注解

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
//1.使用@interface关键字定义注解
public @interface DescriptionAnnotation {
//2.成员以无参数方法方式声明
String desc();

String author();

//3.可以用default为成员制定一个默认值
int age() default 18;
}

(2).使用注解

@DescriptionAnnotation(desc="这是一个类上的注解")
public class Person {
//因为@DescriptionAnnotation的作用范围没有字段ElementType.FIELD,所以报错
//@DescriptionAnnotation(desc="这是一个方法上的注解",author = "Sherry")
private String name;

@DescriptionAnnotation(desc="这是一个方法上的注解",author = "Sherry")
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

(3).解析注解

public class Test {
public static void main(String[] args) throws ClassNotFoundException {
Class personClass = Class.forName("com.steven.annotation.Person");
//1.获取类上所有注解
Annotation[] annotations = personClass.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation instanceof DescriptionAnnotation) {
DescriptionAnnotation descriptionAnnotation = (DescriptionAnnotation) annotation;
System.out.println("desc:" + descriptionAnnotation.desc() + ",author:" + descriptionAnnotation.author());
}
}

//2.获取方法上的注解
Method[] methods = personClass.getMethods();
for (Method method : methods) {
Annotation annotation = method.getAnnotation(DescriptionAnnotation.class);
if (annotation instanceof DescriptionAnnotation) {
DescriptionAnnotation descriptionAnnotation = (DescriptionAnnotation) annotation;
System.out.println("desc:" + descriptionAnnotation.desc() + ",author:" + descriptionAnnotation.author());
}
}
}
}
desc:这是一个类上的注解,author:Steven
desc:这是一个方法上的注解,author:Sherry