注解(7)_元注解_元注解的概念_@Retention_@Target_@Documented_@Inherited

元注解的概念

元注解是用于修饰其他注解的注解。

(1)元注解本身也是注解。
(2)元注解是用来修饰别的注解的。

JDK5.0提供了四种元注解:
@Retention
@Target
@Documented
@Inherited

比如JDK内置的3个注解之一:
@SuppressWarnings

就有元注解:
在这里插入图片描述

元注解_@Retention

看源码:

在这里插入图片描述
配置参数:

RetentionPolicy value();

RetentionPolicy是一个枚举类型

@Retention:用于修饰注解,用于指定修饰的那个注解的生命周期,@Rentention包含一个RetentionPolicy枚举类型的成员变量,使用@Rentention时必须为该value成员变量指定值:

RetentionPolicy.SOURCE

源文件中有效(即源文件保留),编译器直接丢弃这种策略的注释,在.class文件中不会保留注解信息

案例:
比如我自己定义了一个注解叫做MyAnno01:

@Retention(RetentionPolicy.SOURCE)
public @interface MyAnno01 {
    String[] value();
}

并且MyAnno01用Retention元注解修饰,并且传入参数RetentionPolicy.SOURCE,表示在源文件中有效。

然后设置一个Person测试类:(使用MyAnno01)

@MyAnno01({"abc","def"})
public class Person {
    String name;
    int age;
    public void eat(){
        System.out.println("hhhhh");
    }
}

然后重新构建这个项目:
在这里插入图片描述
在out目录中,找到Person类的class文件:
发现没有注解
在这里插入图片描述

这就是 RetentionPolicy.SOURCE 的效果。

RetentionPolicy.CLASS

class文件中有效(即class保留),保留在.class文件中,但是当运行Java程序时,他就不会继续加载了,不会保留在内存中,JVM不会保留注解。如果注解没有加Retention元注解,那么相当于默认的注解就是这种状态。

案例:还是刚才的例子,将Retention元注解传入参数RetentionPolicy.CLASS,表示在字节码文件中有效。

@Retention(RetentionPolicy.CLASS)
public @interface MyAnno01 {
    String[] value();
}

重新编译或者构建项目:(发现在字节码文件中,这个注解仍旧存在)
在这里插入图片描述

RetentionPolicy.RUNTIME

运行时有效(即运行时保留),当运行 Java程序时,JVM会保留注释,加载在内存中了,那么程序可以通过反射获取该注释

元注解_@Target

用于修饰注解的注解,用于指定被修饰的注解能用于修饰哪些程序元素。@Target也包含一个名为value的成员变量。

@Target注解的源码:
在这里插入图片描述
配置参数:

 ElementType[] value();

查看ElementType源码:

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}

ElementType是一个枚举类型,并且有以下几个参数:TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE,TYPE_PARAMETER,TYPE_USE

案例:
准备一个注解:
用@Target修饰:(注意我传参是TYPE,METHOD,CONSTRUCTOR)

@Target({TYPE,METHOD,CONSTRUCTOR})
public @interface MyAnno02 {
}

然后准备一个Dog类:

@MyAnno02
public class Dog {
    @MyAnno02
    String name;
    int age;
    String Type;

    @MyAnno02
    public Dog(String name, int age, String type) {
        this.name = name;
        this.age = age;
        Type = type;
    }

    @MyAnno02
    public void bark(){
        System.out.println("wawawawawawa");
    }
}

发现在成员变量这里是报错的:
在这里插入图片描述
所以例子就大概说明了@Target注解的作用。

在报错的前提下,如果加上@Target中的FIELD参数:

@Target({TYPE,METHOD,CONSTRUCTOR,FIELD})
public @interface MyAnno02 {
}

这时候就不会报错了:
在这里插入图片描述
上面演示了TYPE,METHOD,CONSTRUCTOR,FIELD这四个参数的用法:
TYPE:类、接口(包括注释类型)或枚举声明
METHOD:方法声明
CONSTRUCTOR:构造函数声明
FIELD:字段声明(包括枚举常量)

还有其他参数:
LOCAL_VARIABLE:局部变量声明
ANNOTATION_TYPE:注释类型声明
TYPE_USE:类型的使用
TYPE_PARAMETER:
PACKAGE:包声明
PARAMETER:形式参数声明

元注解_@Documented

用于指定被该元注解修饰的注解类将被javadoc工具提取成文档。默认情况下,javadoc是 不包括注解的,但是加上了这个注解生成的文档中就会带着注解了

案例:
Documented注解修饰了Deprecated注解
(Deprecated注解的源码)
在这里插入图片描述

那么Deprecated注解就会在javadoc提取的时候,提取到API中:
比如Date类的 setSeconds 方法就使用了Deprecated注解:

在这里插入图片描述

API:
在这里插入图片描述

元注解_@Inherited

被它修饰的Annotation将具有继承性。如果某个类使用了被

@Inherited修饰的Annotation,则其子类将自动具有该注解。

案例:

注解:如果MyAnno01注解使用了@Inherited之后,就具备了继承性,那么相当于Person的子类Student也使用了这个MyAnno

@Inherited
@Retention(RetentionPolicy.CLASS)
public @interface MyAnno01 {
    String[] value();
}

父类:
在这里插入图片描述
子类:
在这里插入图片描述

注意:@Documented和@Inherited实际使用较少

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值