Java自定义注解Annotation详解
注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,以后,javac 编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事。标记可以加在包,类,字段,方法,方法的参数以及局部变量上。
public @interface MyAnnotation { //...... }
@MyAnnotation public class AnnotationTest{</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">......</span>
}
Java 中提供了四种元注解,专门负责注解其他的注解,分别如下:
@Retention 元注解,表示需要在什么级别保存该注释信息(生命周期)。可选的 RetentionPoicy 参数包括:
RetentionPolicy.SOURCE: 停留在 java 源文件,编译器被丢掉
RetentionPolicy.CLASS:停留在 class 文件中,但会被 VM 丢弃(默认)
RetentionPolicy.RUNTIME:内存中的字节码,VM 将在运行时也保留注解,因此可以通过反射机制读取注解的信息
@Target 元注解,默认值为任何元素,表示该注解用于什么地方。可用的 ElementType 参数包括
ElementType.CONSTRUCTOR: 构造器声明
ElementType.FIELD: 成员变量、对象、属性(包括 enum 实例)
ElementType.LOCAL_VARIABLE: 局部变量声明
ElementType.METHOD: 方法声明
ElementType.PACKAGE: 包声明
ElementType.PARAMETER: 参数声明
ElementType.TYPE: 类、接口(包括注解类型 ) 或 enum 声明
@Documented 注解将注解包含在 JavaDoc 中
@Inheried 注解允许子类继承父类中的注解
以下写了一个模拟注解的案例:
首先写一个自定义注解 @MyAnnotation,代码如下所示:
package com.pcict.anotation.test;import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MyAnnotation {
// 为注解添加属性
String color();String value() </span><span style="color: rgba(0, 0, 255, 1)">default</span> "我是XXX"; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 为属性提供默认值</span> <span style="color: rgba(0, 0, 255, 1)">int</span>[] array() <span style="color: rgba(0, 0, 255, 1)">default</span> { 1, 2, 3<span style="color: rgba(0, 0, 0, 1)"> }; Gender gender() </span><span style="color: rgba(0, 0, 255, 1)">default</span> Gender.MAN; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 添加一个枚举 </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 添加枚举属性</span> MetaAnnotation metaAnnotation() <span style="color: rgba(0, 0, 255, 1)">default</span> @MetaAnnotation(birthday = "我的出身日期为1988-2-18"<span style="color: rgba(0, 0, 0, 1)">);
}
写一个枚举类 Gender,模拟注解中添加枚举属性,代码如下所示:
package com.pcict.anotation.test;public enum Gender {
MAN {
public String getName() {
return "男";
}
},
WOMEN {
public String getName() {
return "女";
}
}; // 后面记得有“;”
public abstract String getName();
}
写一个注解类 MetaAnnotation,模拟注解中添加注解属性,代码如下:
package com.pcict.anotation.test;public @interface MetaAnnotation {
String birthday();
}
最后写注解测试类 AnnotationTest,代码如下:
package com.pcict.anotation.test;// 调用注解并赋值
@MyAnnotation(metaAnnotation = @MetaAnnotation(birthday = "我的出身日期为 1988-2-18"), color = "red", array = {
23, 26 })
public class AnnotationTest {</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> main(String[] args) { </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 检查类AnnotationTest是否含有@MyAnnotation注解</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (AnnotationTest.<span style="color: rgba(0, 0, 255, 1)">class</span>.isAnnotationPresent(MyAnnotation.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">)) { </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 若存在就获取注解</span> MyAnnotation annotation = (MyAnnotation) AnnotationTest.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> .getAnnotation(MyAnnotation.</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">); System.out.println(annotation); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取注解属性</span>
System.out.println(annotation.color());
System.out.println(annotation.value());
// 数组
int[] arrs = annotation.array();
for (int arr : arrs) {
System.out.println(arr);
}
// 枚举
Gender gender = annotation.gender();
System.out.println("性别为:" + gender);
// 获取注解属性
MetaAnnotation meta = annotation.metaAnnotation();
System.out.println(meta.birthday());
}
}
}
运行 AnnotationTest,输出结果为: