JAVA:浅谈自定义注解

    技术2022-07-20  58

    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被修饰的注解具有继承性

    Processed: 0.014, SQL: 9