注解@Target,@Retention,@Document

/**
 * 系统日志注解
 *
 * @author Mark sunlightcs@gmail.com
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {

	String value() default "";
}

在上述自定义注解中我们发现有三个元注解@Target,@Retention,@Document,但是我们并不知道他们分别代表什么样的含义,接下来我们就详细的解释一下这三个元注解到底如何去使用他们 ?
1:@Target
当标记@Target这个注解就代表这个注解可以应用于那种的java元素类型

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
      *指示注释类型适用的上下文。 的
      *声明上下文和类型上下文,其中注释类型可能是
      *适用于JLS 9.6.4.1中指定,并在源代码中用enum表示
      *返回注释类型的元素数组
      *可以适用。
      *@返回注释类型的元素数组
      *可应用于
    ElementType[] value();
}

从@Target的源码可以看到。ElementType[] 这个枚举类数组

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    /** *用于描述类、接口(包括注解类型) 或enum声明,*/
    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
}

比如:@Target(ElementType.METHOD) 表示只能在方法上声明
在比如:@Target(ElementType.TYPE_PARAMETER) 表示标注类型的参数
如下例子:

@Target(ElementType.TYPE_PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface TypeParameterAnnotation {
     
}

表示该注解@TypeParameterAnnotation 可以用于 泛型声明出

// 如下是该注解的使用例子  用于泛型出
public class TypeParameterClass<@TypeParameterAnnotation T> {
    public <@TypeParameterAnnotation U> T foo(T t) {
        return null;
    }   
}

在@Target注解中 ElementType.TYPE_USE包含了ElementType.TYPE和ElementType.TYPE_PARAMETER

package org.springmorning.demo.javabase.annotation.meta;

/**
 * @author 春晨
 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10264624.html
 */
import java.util.ArrayList;

//泛型类型声明时,使用TYPE_USE类型,编译通过
class A <@NotNull TT>{}

//泛型类型声明时,使用使用TYPE_PARAMETER类型,编译通过
public class TypeParameterAndTypeUseAnnotation<@NotEmpty T>{

    //使用TYPE_PARAMETER类型,会编译不通过
//    public @NotEmpty T test(@NotEmpty T a){
//        new ArrayList<@NotEmpty String>();
//            return a;
//    }

    //使用TYPE_USE类型,编译通过
    public @NotNull T test(@NotNull T a){
        new ArrayList<@NotNull String>();
        return a;
    }
}

@Retention 元注解 注解标记其他的注解用于指明标记的注解保留策略

从源代码的看到

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

定义元注解@Retention定义的数据是RetentionPolicy枚举值数组

/**
 * Annotation retention policy.  The constants of this enumerated type
 * describe the various policies for retaining annotations.  They are used
 * in conjunction with the {@link Retention} meta-annotation type to specify
 * how long annotations are to be retained.
 *
 * @author  Joshua Bloch
 * @since 1.5
 */
public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     * 表示注解会在编译时被丢弃
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     *  默认策略,表示注解会在编译后的class文件中存在,但是在运行时,不会被VM保留。
     */ 
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *表示不仅会在编译后的class文件中存在,而且在运行时保留,因此它们主要用于反射场景,可以通过getAnnotation方法获取
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

首先要明确生命周期长度 SOURCE < CLASS < RUNTIME ,所以前者能作用的地方后者一定也能作用。
一般如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解,比如@RestController使用RUNTIME注解
如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife),就用 CLASS注解;
如果只是做一些检查性的操作,比如 @Override 和 @SuppressWarnings,使用SOURCE 注解。
注解@Deprecated,用来表示某个类或属性或方法已经过时,不想别人再用时,在属性和方法上用@Deprecated修饰
如:
@RestController

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {

	/**
	 * The value may indicate a suggestion for a logical component name,
	 * to be turned into a Spring bean in case of an autodetected component.
	 * @return the suggested component name, if any (or empty String otherwise)
	 * @since 4.0.1
	 */
	@AliasFor(annotation = Controller.class)
	String value() default "";

}

我们可以使用javap -verbose class文件去分析可以看到自己定义的注解,当标记RUTINE那么在运行时是可以看到注解里面包含的参数

如果采用声明时采用的保留策略是CLASS,在运行时是看不到参数的

@Documented注解标记的元素,Javadoc工具会将此注解标记元素的注解信息包含在javadoc中。默认,注解信息不会包含在Javadoc中。示例如下:
声明Book注解,并使用@Document标记:

package org.springmorning.demo.javabase.annotation.meta;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;

/**
 * @author 春晨
 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10261472.html
 */
@Documented
@Inherited
public @interface Book {

    //书名
    String name();

    //出版日期
    String publishedDate();

    //作者
    String author();
}

使用@Book注解标记类DocumentAnnotation,Book标记元素内容如下:

package org.springmorning.demo.javabase.annotation.meta;

/**
 * @author 春晨
 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10261472.html
 */
@Book(
        name = "Spring in Action",
        author = "Craig Walls",
        publishedDate = "2008-10-1"
)
public class DocumentAnnotation {}

打开cmd 输入javadoc命令:

javadoc -d D:\doc org.springmorning.demo.javabase.annotation.meta -encoding utf-8 -charset utf-8

说明:

-d D:\doc 表示:doc文件输入目录为D盘的doc文件夹;

org.springmorning.demo.javabase.annotation.meta 表示此包中所有类需要生成java doc html文件;

-encoding utf-8 表示:java代码采用的是utf-8字符编码编写的;

-charset utf-8 表示:java doc html文件为utf-8字符编码。

再生成的java.doc文件 可以看到被@Document修饰的话都可以在java.doc文档中看的到

参考博客:
https://www.cnblogs.com/springmorning/p/10261472.html
https://www.cnblogs.com/springmorning/p/10265030.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值