1.2.12 注解总结

1.2.12 注解

1.2.12.1 概念

注解是一种能被添加到java代码中的元数据,类、方法、变量、参数和包都可以用注解来修饰。注解对于它所修饰的代码并没有直接的影响。这些在标记可以在编译、类加载、运行时被读取,并执行相应的处理。

作用

  • 为编译器提供信息 注解能被编译器检测到错误或抑制警告。
  • 编译时和部署时的处理 软件工具能处理注解信息从而生成代码,XML文件等等。
  • 运行时的处理 有些注解在运行时能被获取到。

分类

  • 内置注解
    • java.lang 包中包含: @Override、@Deprecated、@SuppressWarnings、@SafeVarargs、@FunctionaInterface
    • 元注解: @Retention、@Document、@Target、@Inherited、@Repeatable
  • 自定义注解
    • 各框架自定义注解: 如 Spring @Bean、@Component、@Service、@Controller 等; Lombok @Get、@Set…
    • 用户定义注解

1.2.12.2 JDK 原生注解

常见 JDK lang 包中包含的注解,主要作用是辅助代码检查。

注解说明
Override当前方法覆盖了父类的方法
Deprecated表示方法或类不再建议使用
SuppressWarnings编译器忽略特定的编译警告
SafeVarargs忽略变长参数使用泛型作为形参的警告
FunctionalInterface用来指定某个接口必须是函数式接口,用在有且仅有一个抽象方法的接口

1.2.12.3 元注解

元注解是用于定义其他注解的注解。

注解说明
Target表示注解使用范围
Retention表示在什么级别保存该注解信息
Documented将此注解包含再javadoc中
Inherited子类继承父类中的注解
Repeatable允许一个注解在一个元素上使用多次
Native修饰成员变量,表示这个变量可以被本地代码引用,常常被代码生成工具使用

Target

@Target(java.lang.annotation.ElementType) 表示注解可使用范围

ElementType说明
TYPE接口、类、枚举、注解
FIELD字段、枚举的常量
METHOD方法
PARAMETER方法参数
CONSTRUCTOR构造函数
LOCAL_VARIABLE局部变量
ANNOTATION_TYPE注解
PACKAGE

Retention

@Retention(RetentionPolicy) 表示需要在什么级别保存该注释信息。

RetentionPolicy说明
SOURCE源文件,注解不参与编译,也不在运行期间起作用,相当于注释
CLASS默认值,编译有效,编译器可以根据注解做一些处理,但 JVM 会忽略它,运行期也无法获取
RUNTIME运行时有效,会被加载到 Class 对象中,可以通过反射获取注解和值

Documented

@Documented 要求 Javadoc 工具将此注解标记元素的注解信息包含在 javadoc 中。

示例
    @Documented
    public @interface Book {
        //书名
        String name();

        //出版日期
        String publishedDate();

        //作者
        String author();
    }

    @Book(
        name = "Spring in Action",
        author = "Craig Walls",
        publishedDate = "2008-10-1"
    )
    public class Varargs {

        public static void main(String[] args) {

        }
    }
  • Doc 文档 截图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dbcAupX9-1627983803208)(…/…/img/annotation_documented.png)]

Inherited

父类使用 @Inherited 的注解会被子类继承

  • 定义在类上的注解会被继承
  • 定义在方法和属性上的注解,只有在未被重写(或实现)才会被继承

Repeatable

@Repeatable 修饰的注解,可以在同一个地方使用多次。

使用步骤示例
  1. 定义需要使用 Repeatable 的注解
    @Retention(RetentionPolicy.RUNTIME)
    @Repeatable(RepeatableContainer.class)
    public @interface RepeatableAnnotation {

        String value();
    }
  1. 定义使用 Repeatable 容器注解
    @Retention(RetentionPolicy.RUNTIME)
    public @interface RepeatableContainer {

        RepeatableAnnotation[] value();
    }
  1. 使用注解
    @RepeatableAnnotation("a")
    @RepeatableAnnotation("b")
    public class RepeatableTest {

        public static void main(String[] args) {

            RepeatableAnnotation[] annotationsByType = RepeatableTest.class.getAnnotationsByType(RepeatableAnnotation.class);
            for (RepeatableAnnotation repeatableAnnotation : annotationsByType) {
                System.out.println(repeatableAnnotation.value());
            }
        }
    }

输出:

a
b

注意事项,上例中注解都需要设定 Retention = RUNTIME,否则无法执行。

Native

使用 @Native 注解修饰成员变量,则表示这个变量可以被本地代码引用,常常被代码生成工具使用。不常使用,了解即可。

1.2.12.4 使用

定义关键字

    public @interface CherryAnnotation {
    }

注解定义关键字时 @interface,在底层实现上,所有定义的注解都会自动继承 java.lang.annotation.Annotation 接口。

定义注解类型元素

    public @interface CherryAnnotation {
        public String name();
        int age() default 18;
        int[] array();
    }

注解类型元素的语法非常奇怪,即又有属性的特征(可以赋值),又有方法的特征(打上了一对括号)。但是这么设计是有道理的,我们在后面的章节中可以看到:注解在定义好了以后,使用的时候操作元素类型像在操作属性,解析的时候操作元素类型像在操作方法。

定义注解类型元素时需要注意如下几点:

  1. 访问修饰符必须为 public,不写默认为 public;
  2. 该元素的类型只能是基本数据类型、String、Class、枚举类型、注解类型(体现了注解的嵌套效果)以及上述类型的一位数组
  3. 该元素的名称一般定义为名词,如果注解中只有一个元素,请把名字起为 value(后面使用可以不指定属性名)
  4. () 不是定义方法参数的地方,也不能在括号中定义任何参数,仅仅只是一个特殊的语法
  5. default 代表默认值,值必须和第 2 点定义的类型一致
  6. 如果没有默认值,代表后续使用注解时必须给该类型元素赋值

通过反射获取注解

  1. 如果我们要获得的注解是配置在方法上的,那么我们要从 Method 对象上获取;如果是配置在属性上,就需要从该属性对应的 Field 对象上去获取,如果是配置在类型上,需要从 Class 对象上去获取。总之在谁身上,就从谁身上去获取!
  2. isAnnotationPresent(Class<? extends Annotation> annotationClass) 方法是专门判断该元素上是否配置有某个指定的注解;
  3. getAnnotation(Class<A> annotationClass) 方法是获取该元素上指定的注解。之后再调用该注解的注解类型元素方法就可以获得配置时的值数据;
  4. 反射对象上还有一个方法 getAnnotations(),该方法可以获得该对象身上配置的所有的注解。它会返回给我们一个注解数组,需要注意的是该数组的类型是 Annotation 类型,这个 Annotation 是 java.lang.annotation 包中的接口。

更详细的自定义注解介绍 https://blog.csdn.net/xsp_happyboy/article/details/80987484

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值