简介
注解是 JDK5.0 引入的一种注释机制,本文基于JDK1.8的基础上主要讲解注解的语法及使用。
元注解
@Documented
在生成JavaDoc的时候,会将该注解显示出来。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
@Target
用于设定该注解适用范围。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* 返回注释可应用于某种元素类型的数组。
*/
ElementType[] value();
}
public enum ElementType {
/** 可用于类、接口、枚举 */
TYPE,
/** 可用于字段(包含枚举常量) */
FIELD,
/** 可用于方法 */
METHOD,
/** 可用于参数 */
PARAMETER,
/** 可用于构造方法 */
CONSTRUCTOR,
/** 可用于局部变量 */
LOCAL_VARIABLE,
/** 可用于注解 */
ANNOTATION_TYPE,
/** 可用于包上,用于记录Java文件的package信息 */
PACKAGE,
/**
* 可用于泛型参数
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* 用于类型声明和类型参数声明
*
* @since 1.8
*/
TYPE_USE
}
@Retention
用来标识这个注解将如何保留。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* 返回注解的保留策略
* @return 保留策略
*/
RetentionPolicy value();
}
/**
* 注解保留策略。
* 与@Retention元注解一起使用,指定注解要保留多长时间
*/
public enum RetentionPolicy {
/**
* 注解将被编译器丢弃,只在源码中保留。
*/
SOURCE,
/**
* 注解由编译器记录在类文件中,但在JVM将被忽略。
*/
CLASS,
/**
* 注解由编译器记录在类文件中并且在JVM在运行时保留,因此可以通过反射读取。
*/
RUNTIME
}
周期长度升序为:RetentionPolicy.
SOURCE
< RetentionPolicy.CLASS
< RetentionPolicy.RUNTIME
@Inherited
该注解作用于某父类时,该注解会被父类的子类继承。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
代码示例
import java.lang.annotation.*;
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Properties {
}
@Properties
public abstract class Parent {
}
public class Child extends Parent {
}
public class Run {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> parentClass = Class.forName("demo1.Parent");
System.out.println(parentClass.isAnnotationPresent(Properties.class));
Class<?> childClass = Class.forName("demo1.Child");
System.out.println(childClass.isAnnotationPresent(Properties.class));
}
}
执行结果如下:
true
true
@Repeatable
@Repeatable用于声明当前注解是可以重复的。
@Repeatable声明注解的保留周期要小于或等于@Repeatable的周期。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
Class<? extends Annotation> value();
}
代码示例
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.RUNTIME)
public @interface Roles {
Role[] value();
}
@Repeatable(Roles.class)
public @interface Role {
String value();
}
@Role("女儿")
@Role("妻子")
@Role("母亲")
public class People {
}
public class Run {
public static void main(String[] args) throws ClassNotFoundException {
Class people = Class.forName("demo2.People");
Role[] roles = (Role[]) people.getAnnotationsByType(Class.forName("demo2.Role"));
for (Role role : roles) {
System.out.println(role.value());
}
}
}
输出信息如下:
女儿
妻子
母亲