@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
:注解标记其他的注解用于指明标记的注解是可以被自动继承的。
注意:此注解只对注解标记的超类有效,对接口是无效的。