注解,主要jdk包:java.lang.annotation
元注解:@Documented,@Retention,@Target,@interface
元注解就是只能用于其他注解上的注解。。他们的目标位置都为@Target(ElementType.ANNOTATION_TYPE)
@Document:拥有这个元注解的注解才可以被javadoc此类的工具文档化,该元注解没有属性
@Retention:指定注解的生命周期,有value属性,值为RetentionPolicy类型
RetentionPolicy.SOURCE - 注解会被编译器丢弃,只存在于源码中,编译后丢失
RetentionPolicy.CLASS - 注解会被编译器记录到class文件里去,但是在vm运行时注解不会保留
RetentionPolicy.RUNTIME - 注解会被编译器记录到class文件里去,在vm运行时注解也会存在,所以可以被反射读取注解信息
@Target:指定注解可存在的目标位置,有value属性,值为ElementType[]类型
ElementType枚举元素有:TYPE、FIELD、METHOD、PARAMETER、ANNOTATION_TYPE等,具体值代表含义可直接看jdk源代码ElementType类注释
@Inherited:指定注解可被继承,如果使用了@Inherited元注解的注解被用在一个Class上,则这个注解会被这个Class的子类继承,该元注解没有属性
自定义注解:
使用@interface关键字来定义注解;
定义的注解自动继承java.lang.annotation.Annotation接口,不能有其他extends或implements;
注解里可以定义方法,修饰符默认为public,方法名就是注解的一个属性名,方法不能有参数,方法返回类型就是属性值(只能是基本类型以及String、Class、Enum、Annotation,以及这些类型的数组类型),方法可以有默认值用default指定;
示例:
自定义注解HelloAnnotation类
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface HelloAnnotation {
int id() default 0;
String name() default "Hello, Annotation";
String value();
}
自定义注解测试类
import java.lang.reflect.Method;
@HelloAnnotation("Class")
public class TestHelloAnnotation {
@HelloAnnotation(value = "Method", id = 2)
public void test() {}
public static void main(String[] args) throws NoSuchMethodException {
TestHelloAnnotation testHelloAnnotation = new TestHelloAnnotation();
if(testHelloAnnotation.getClass().isAnnotationPresent(HelloAnnotation.class)) {
HelloAnnotation helloAnnotation = testHelloAnnotation.getClass().getAnnotation(HelloAnnotation.class);
System.out.println(helloAnnotation.id());
System.out.println(helloAnnotation.name());
System.out.println(helloAnnotation.value());
}
Method method = testHelloAnnotation.getClass().getMethod("test");
if(method.isAnnotationPresent(HelloAnnotation.class)) {
HelloAnnotation helloAnnotation = method.getAnnotation(HelloAnnotation.class);
System.out.println(helloAnnotation.id());
System.out.println(helloAnnotation.name());
System.out.println(helloAnnotation.value());
}
}
}
Class、Field、Method、Parameter等类都可以通过isAnnotationPresent()方法判断是否有注解,通过getAnnotation()/getAnnotations()方法来获取注解对象,使用注解对象的方法获取注解对象属性值来操控逻辑等
另外:
@Override注解上@Retention(RetentionPolicy.SOURCE);
@SuppressWarnings注解上@Retention(RetentionPolicy.SOURCE);
@Deprecated注解上@Retention(RetentionPolicy.RUNTIME);