怎么实现一个自定义注解
注解是Java提供了一种原程序中的元素关联任何信息和着任何原数据的途径和方法,Annotation是一个接口,程序可通过反射来获取指定程序元素的Annotion对象,然后通过Annotion对象来获取注解里面的元数据。
annotation 提供了四种元注解,专门注解其他的注解(在自定义注解的时候,需要使用到元注解):
@Target和@Retention是元注解(用于给其它注解,一般自定义注解都要使用) 注解主要分以下几类:
1.系统注解:JDK提供了三个系统注解Override(标记此方法是覆盖了父类的方法)、
Deprecated(用于标记方法等过时,一般都会有新的API提供)、
SuppressWarnnings(用于通知Java编译器禁止特定的编译警告)
2.元注解:Java5.0定义了4个标准的meta-annotation类型
(1)@Target:用于说明Annotation所修饰的范围,
@Target({ElementType.ANNOTION_TYPE})
ElementType是个枚举类型,取值有:
1.CONSTRUCTOR:用于描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述参数
7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
(2)@Retention:定义Annotion被保留的时间长短即注解生命周期限制
@Retention(RetentionPolicy.RunTime)
RetentionPolicy也是枚举类,取值有:
1.SOURCE:在源文件中有效(即源文件保留,被编译器丢弃)
2.CLASS:在class文件中有效(即class保留,被编译但虚拟机忽略)
3.RUNTIME:在运行时有效(即运行时保留,class装载的时候读取)
(3)@Documented:用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如Javadoc此类的工具文档化
(4)@Inherited:用于标记注解是可以被继承的,如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类;
下面将实际实现一个注解:
当注解里面只有一个方法时,可省略方法名=…的定义,如@test(“123”),此时注解test中只有一个方法,
定义test注解:
import java.lang.annotation.*;
@Target({ElementType.FIELD,ElementType.METHOD}) //表示此注解即可以用于属性也可用于方法
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface test {
String value() default "";
String fieldName() default "";
}
使用test注解的实体:
public class TestEntity {
@TestAnnotation(value = "TestAnnotation value")
private String value;
@TestAnnotation(fieldName = "TestAnnotation fieldName")
private String fieldName;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
}
对注解进行处理:
import java.lang.reflect.Field;
public class UseTestAnnotaion {
public static void getInfo(Class<?> clazz){
Field[] fields = clazz.getDeclaredFields();
for (Field field:fields){
if(field.isAnnotationPresent(TestAnnotation.class)){
TestAnnotation annotation = field.getAnnotation(TestAnnotation.class);
System.out.println(annotation.fieldName());
System.out.println(annotation.value());
}
}
}
}
运行处理方法:
import org.junit.Test;
public class TestRun {
@Test
public void run(){
UseTestAnnotaion.getInfo(TestEntity.class);
}
}
运行结果:
获得类上所有注解的方法
Annotation[] annotations = clazz.getDeclaredAnnotations(); // clazz为实体类的反射,Entity.class
获得属性上所有注解的方法
Annotation[] annotations = field.getDeclaredAnnotations();
获得方法上所有注解的方法
Annotation[] annotations = method.getDeclaredAnnotations();
未完待续。。。