Java8 注解

随着 Spring Boot 等各种框架的日渐流行,Java 注解越来越重要,Java 8 进一步扩展了注解的功能,本文基于 Java8 总结注解的基础知识。

元注解

元注解是用于修饰注解的注解,通常用在注解的定义上。

@Target

注解作用的目标,取值定义在 java.lang.annotation.ElementType,如果没有声明,默认适用于所有的类型。

VALUE DESC
TYPE Class, interface (包括 annotation), 或 enum
FIELD 字段,包括枚举常量
METHOD 方法
PARAMETER 方法参数
CONSTRUCTOR 构造方法
LOCAL_VARIABLE 本地变量
ANNOTATION_TYPE 注解
PACKAGE
TYPE_PARAMETER 泛型的类型参数
TYPE_USE 使用泛型类型参数

@Retention

注解的生命周期,取值定义在 java.lang.annotation.RetentionPolicy,如果没有声明,则默认为 CLASS。

VALUE DESC
SOURCE 只在源码中保留,不会编译到字节码
CLASS 保留到字节码,但不一定加载到内存
RUNTIME 保留到运行时

@Documented

注解是否应当被包含在 JavaDoc 文档中

@Inherited

是否允许子类继承该注解

可重复的注解

Java8 新增了可重复标注的注解,重复注解本身必须用 @Repeatable 注解,并提供一个容器注解,本质上是一个语法糖,示例如下:

package com.hiwzc.java.demo;

import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Repeatable(Tests.class)
@Retention(RetentionPolicy.RUNTIME)
@interface Test {
    String value();
}

@Retention(RetentionPolicy.RUNTIME)
@interface Tests {
    Test[] value();
}

@Test("AAA")
@Test("BBB")
public class RepeatableAnnotationDemo {
    public static void main(String[] args) {
        Test[] tests = RepeatableAnnotationDemo.class.getAnnotationsByType(Test.class);
        for (Test test : tests) {
            System.out.println(test.value());
        }
    }
}

泛型类型的注解

用于标记泛型的类型参数,示例如下:

package com.hiwzc.java.demo;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target(ElementType.TYPE_PARAMETER)
@interface TypeParamAnno {

}

@Target(ElementType.TYPE_USE)
@interface TypeAnno {

}

public class TypeAnnotation<@TypeParamAnno T> {

    private @TypeAnno T val;

    public <@TypeParamAnno U> void foo(@TypeAnno U u) {

    }
}