Java创建自定义注解所需要使用的几个元注解

@Target:该注解用于标识,当前注解可以放在哪些位置。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    
    
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

所需属性是一个ElementType类型的数组,这个类型是个枚举类。

public enum ElementType {
    
    
    TYPE,  // 可以放在类、接口

    FIELD, // 成员变量

    METHOD, // 方法

    PARAMETER, // 入参

    CONSTRUCTOR, // 构造函数

    LOCAL_VARIABLE, // 本地变量

    ANNOTATION_TYPE, 

    PACKAGE,
    
    TYPE_PARAMETER,

    TYPE_USE
}

@Retention :用于标识注解生命周期范围,参数是RetentionPolicy

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    
    
    RetentionPolicy value();
}
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 {
    
    
    /**
     * 指的是该注解将在编译期被丢弃,注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
     */
    SOURCE,

    /**
     * 注解信息将会在编译期被记录、但是不在代码在VM运行时维持,注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;
     */
    CLASS,

    /**
     * 注解将会在VM执行时维持注解信息,贯穿整个生命周期,注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;需要用到反射都需要使用这个
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

生命周期 SOURCE < CLASS < RUNTIME

@Documented:Javadoc工具会将此注解标记元素的注解信息包含在javadoc中。默认,注解信息不会包含在Javadoc中

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
    
    
}

示例:

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

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

@Documented
@Inherited
public @interface Book {
    
    
    //书名
    String name();
    //出版日期
    String publishedDate();
    //作者
    String author();
}

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

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

@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字符编码。

运行结果:
在这里插入图片描述
javadoc 命令生成的java doc文档:

在这里插入图片描述
浏览器打开index.html查看里面的内容,可以看到@Book注解的文档说明:
在这里插入图片描述
点左侧栏中的“DocumentAnnotation",打开DocumentAnnotation类的文档说明,可以看到@Book标记的注解内容显示了出来:
在这里插入图片描述
如果@Book注解没有被@Document标记,那么被@Book注解标记的DocumentAnnotation类的注解信息就不会包含在java doc html文档中:如下图在这里插入图片描述
@Repeatable:java8以后支持在同一个地方(某个方法或者某个类等)加上相同的注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
    
    
    /**
     * Indicates the <em>containing annotation type</em> for the
     * repeatable annotation type.
     * @return the containing annotation type
     */
    Class<? extends Annotation> value();
}

我们先创建一个自定义注解:

@Retention(RetentionPolicy.RUNTIME)
@Target({
    
    ElementType.METHOD, ElementType.TYPE})
@Repeatable(CustomAnnotations.class)
public @interface CustomAnnotation {
    
    
    int type();
}

该注解的属性为 Class<? extends Annotation>,也就是说这里需要一个是继承Annotation的一个类(注解类)。这里创建了一个另一个自定义注解,后面称之为父注解,之前的称之为子注解,示例代码如下:

@Retention(RetentionPolicy.RUNTIME)
@Target({
    
    ElementType.METHOD, ElementType.TYPE})
public @interface CustomAnnotations {
    
    
    CustomAnnotation[]  value();
}

父注解必须有以下特征:
1:作用域必须大于等于子注解
2:父注解的周期要比子注解的周期要小或相同(注意:SOURCE(源码) < CLASS (字节码) < RUNTIME(运行))
3:父注解的value的类型是子注解类型的数组

@Inherited:注解标记其他的注解用于指明标记的注解是可以被自动继承的。

注意:此注解只对注解标记的超类有效,对接口是无效的。

猜你喜欢

转载自blog.csdn.net/qq_16733389/article/details/126745015