Target注解与Retention注解的理解

前言

学习Java的同志们都知道注解在java开发中起到简化开发的作用,让许多代码都不用重复的写,显示的写,特别是各种框架(比如Spring、MyBatis等)可以说是基于注解开发的。在本文则为大家介绍一下@Target和@Retention这2个注解,也是一种学习,打字不易,希望各位同志手动三连(点赞+评论+收藏)


正文

元注解

首先@Target和@Retention都是属于元注解的范畴,那什么是元注解呢?最原始的注解,简单来说就是用来修饰注解的注解,除了@Target和@Retention以外,@Documented和@Inherited也是一种元注解。

Target注解


Indicates the contexts in which an annotation type is applicable. The declaration contexts and type contexts in which an annotation type may be applicable are specified in JLS 9.6.4.1, and denoted in source code by enum constants of java.lang.annotation.ElementType.
指示注释类型适用的上下文。注释类型可能适用的声明上下文和类型上下文在JLS 9.6.4.1中指定,并在源代码中用java.lang.annotation.ElementType的枚举常量表示。

关于Target注解官方的解释是指示注释类型适用的上下文,也就指明注解可以修饰的范围。常见修饰类的、修饰方法的、修饰变量的等这些,具体范围通过java.lang.annotation.ElementType的枚举进行声明,具体含义如下所示。


public enum ElementType {
    /** 用在描述类、接口(包括注解类型)或枚举 */
    TYPE,
    /** 用在字段声明(包括枚举) */
    FIELD,
    /** 用于方法上 */
    METHOD,
    /** 用在参数上 */
    PARAMETER,
    /** 用在构造器(又叫构造方法)上 */
    CONSTRUCTOR,
    /** 用在局部变量上 */
    LOCAL_VARIABLE,
    /** 用在描述注释上 */
    ANNOTATION_TYPE,
    /** 用在包上 */
    PACKAGE,
    /** 从1.8开始支持,自定义类型参数上 */
    TYPE_PARAMETER,
    /** 从1.8开始支持,对类型注解 */
    TYPE_USE
}

还有就是任何注解都要有@Target修饰,哪怕它自己也是,修饰的类型是ANNOTATION_TYPE,即对注解进行修饰。


@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
   
    ElementType[] value();
}

Retention注解

关于Retention注解指示具有注释类型的注释要保留多长时间,按我的理解就是注解的生命周期的范围。具体范围通过java.lang.annotation.RetentionPolicy的枚举值进行声明,有3个值,分别是SOURCE(源文件)、CLASS(编译文件)和RUNTIME(运行时),

  • SOURCE 代表着注解仅保留在源文件中,编译后遗弃。

  • CLASS 代表着注解被保留在class文件中,启动后遗弃。

  • RUNTIME 代表着标记的注解会由JVM保留,因此运行时环境可以使用它。

跟@Target一样,每一个注解也需要用@Retention进行修饰的。


/**
 * Indicates how long annotations with the annotated type are to
 * be retained.  If no Retention annotation is present on
 * an annotation type declaration, the retention policy defaults to
 * {@code RetentionPolicy.CLASS}.
 * 指示具有注释类型的注释要保留多长时间。如果注释类型声明中不存在Retention注释,
 * 则保留策略默认为RetentionPolicy.CLASS。
 *
 * <p>A Retention meta-annotation has effect only if the
 * meta-annotated type is used directly for annotation.  It has no
 * effect if the meta-annotated type is used as a member type in
 * another annotation type.
 * 只有当元注释类型直接用于注释时,保留元注释才有效。如果元注释类型被用作另一个注释类型中
 * 的成员类型,则此操作无效。
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}

Retention注解具体作用,我看到一个帖子上有人评论说:既然SOURCE和CLASS在运行环境时无法使用,那么他们有什么用?

那么他们有什么用,这个我就不得不提一下Lombok了,就拿@Data注解来说,他是被声明为SOURCE的,意味着编译后,这个注解会被舍弃。

编译前:

编译后:

可以看到@Data注解确实没了,但同时我也们也可以看到多了许多方法,get/set/构造方法等。那么这一步有没有用呢?答案是肯定的,首先简化开发,不用重复的写get/set/构造方法;其次结构更为简明,有些实体类属性贼多,加上get/set方法这个类文件就很庞大了,浏览起来也很迷糊,跟屎山一样。

看到一个公式:

框架=注解+反射+设计模式

个人觉得这个公式总结的还是挺到位的,注解为我们封装了繁琐的代码,并且使用更简单。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值