JAVA:浅谈自定义注解

Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。
Java 语言中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义 Java 标注。
自定义注解:

1.自定义注解需要使用 @interface 来开发,类似于开发一个接口

//声明一个名字为Note的注解
public @interface Note {
}

2.自定义注解,需要使用元注解来声明自定义注解的特性

2.1 @Target

用来声明注解可以放在什么位置,如果不写,则可以用在任何位置
ElementType.ANNOTATION_TYPE:———用在注解
ElementType.CONSTRUCTOR:—————用在构造函数
ElementType.FIELD:—————————字段、枚举的常量
ElementType.LOCAL_VARIABLE:———局部变量
ElementType.METHOD ———————方法
ElementType.PACKA————————包
ElementType.PARAMETER:————方法参数
ElementType.TYPE: ———————接口、类、枚举、注解

/*声明一个只能在方法前使用的注解*/
@Target({ElementType.METHOD})
@interface Note {
}

2.2 @Retention 用来声明被修饰的注解会被保留到什么阶段

可以在该注解的属性中,通过RetentionPolicy类型的值来指定注解被保留到何时。
a.RetentionPolicy.SOURCE
此注解会保留到源码阶段(.java文件)中在编译过程中被删除。
这种类型的注解通常是为了在编译时给出提示。
b.RetentionPolicy.CLASS
此注解将会被保留到源码阶段和编译阶段(.java文件和.class文件)中,在类加载过程中被删除。
这种类型的注解通常是为了提供给类加载器用。
c.RetentionPolicy.RUNTIME
此类注解会被保留在源码阶段(.java文件)、编译阶段(.class文件)、运行阶段(内存中的字节码)中。
这种类型的注解通常用来运行时提供程序的控制,一般用于反射机制控制程序的运行过程。
也只有RUNTIME级别的注解才能通过反射技术完成反射相关的操作,Spring框架大量使用了该技术

//定义一个可以用于反射的注解
@Retention(RetentionPolicy.RUNTIME)
@interface Note {
}

2.3 @Documented

用来声明被修饰的注解是否要被文档提取工具提取当文档中。
默认情况下,javadoc是不包括注解的. 但如果声明注解时指定了@Documented,则它会被 javadoc 之类的工具处理

//当使用javadoc命令生成可读文档的时候,该注解会出现在文档中
@Documented
@interface Note {
}

2.4 @Inherited被修饰的注解具有继承性

默认没有继承性,当使用了该标签之后,被注解标记的类将自动继承该注解中的方法。
由于要继承,所以要使用@Inherited修饰前,需要使用@Retention(RetentionPolicy.RUNTIME)修饰,只有这样文件才能完成反射传值,如果不使用反射传值,则不需要@Retention(RetentionPolicy.RUNTIME)修饰

//定义一个可以被反射注解
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface InheritedTest {
    String value();
}

使用上面自定义的注解修饰一个新的类,并且通过注解为新的类添加说明

@InheritedTest(value = "Ben从注解中获得的值")
public class Ben {
}

由于被@Inherited被修饰的注解是否具有继承性,所以Ben的子类也会有Ben的说明

//BenSong这个类继承了Ben类,那么BenSon中就应该含有Ben从注解中获得的值
public class BenSon extends Ben{
}

测试一下继承属性是否存在,这里用了反射方式

    public static void main(String[] args) {
        Class<BenSon> benSonClass = BenSon.class;
        //判断BenSon是否继承了Ben类中的注解
        if (benSonClass.isAnnotationPresent(InheritedTest.class)){
            //如果继承了注解,则输出注解中的类容。
            System.out.println(benSonClass.getAnnotation(InheritedTest.class).value());
        }
    }

得到的结果:成功输出了父类Ben中的值,得到结论@Inherited被修饰的注解具有继承性
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章