Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。 Java 语言中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义 Java 标注。 自定义注解:
用来声明注解可以放在什么位置,如果不写,则可以用在任何位置 ElementType.ANNOTATION_TYPE:———用在注解 ElementType.CONSTRUCTOR:—————用在构造函数 ElementType.FIELD:—————————字段、枚举的常量 ElementType.LOCAL_VARIABLE:———局部变量 ElementType.METHOD ———————方法 ElementType.PACKA————————包 ElementType.PARAMETER:————方法参数 ElementType.TYPE: ———————接口、类、枚举、注解
/*声明一个只能在方法前使用的注解*/ @Target({ElementType.METHOD}) @interface Note { }可以在该注解的属性中,通过RetentionPolicy类型的值来指定注解被保留到何时。 a.RetentionPolicy.SOURCE 此注解会保留到源码阶段(.java文件)中在编译过程中被删除。 这种类型的注解通常是为了在编译时给出提示。 b.RetentionPolicy.CLASS 此注解将会被保留到源码阶段和编译阶段(.java文件和.class文件)中,在类加载过程中被删除。 这种类型的注解通常是为了提供给类加载器用。 c.RetentionPolicy.RUNTIME 此类注解会被保留在源码阶段(.java文件)、编译阶段(.class文件)、运行阶段(内存中的字节码)中。 这种类型的注解通常用来运行时提供程序的控制,一般用于反射机制控制程序的运行过程。 也只有RUNTIME级别的注解才能通过反射技术完成反射相关的操作,Spring框架大量使用了该技术。
//定义一个可以用于反射的注解 @Retention(RetentionPolicy.RUNTIME) @interface Note { }用来声明被修饰的注解是否要被文档提取工具提取当文档中。 默认情况下,javadoc是不包括注解的. 但如果声明注解时指定了@Documented,则它会被 javadoc 之类的工具处理
//当使用javadoc命令生成可读文档的时候,该注解会出现在文档中 @Documented @interface Note { }默认没有继承性,当使用了该标签之后,被注解标记的类将自动继承该注解中的方法。 由于要继承,所以要使用@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被修饰的注解具有继承性