Annotation 注解快速入门
1 、注解的定义
Annontation是Java5开始引入的新特征,中文名称叫注解。它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。为程序的元素(类、方法、成员变量)加上更直观更明了的说明,这些说明信息是与程序的业务逻辑无关,并且供指定的工具或框架使用。Annontation像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。
Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。
1.1 元注解
java.lang.annotation提供了四种元注解,专门注解其他的注解(在自定义注解的时候,需要使用到元注解):
@Documented –注解是否将包含在JavaDoc中
@Retention –什么时候使用该注解
@Target –注解用于什么地方
@Inherited – 是否允许子类继承该注解
@Retention– 定义该注解的生命周期
● RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
● RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式
● RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
非常关键,默认设置反射是获取不到的,设置成RUNTIME在运行时可以获取
Target – 表示该注解用于什么地方
默认值为任何元素,表示该注解用于什么地方。可用的ElementType参数包括
● ElementType.CONSTRUCTOR:用于描述构造器
● ElementType.FIELD:成员变量、对象、属性(包括enum实例)
● ElementType.LOCAL_VARIABLE:用于描述局部变量
● ElementType.METHOD:用于描述方法
● ElementType.PACKAGE:用于描述包
● ElementType.PARAMETER:用于描述参数
● ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明
@Documented–表示是否将注解信息添加在java文档中
@Inherited – 定义该注释和子类的关系
@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
1.2 内置注解
Deprecated 注解
可以修饰类、方法、变量,在java源码中被@Deprecated修饰的类、方法、变量等表示不建议使用的,可能会出现错误的,可能以后会被删除的类、方法等,如果现在使用,则在以后使用了这些类、方法的程序在更新新的JDK、jar包等就会出错,不再提供支持。
个人程序中的类、方法、变量用@Deprecated修饰同样是不希望自己和别人在以后的时间再次使用此类、方法。当编译器编译时遇到了使用@Deprecated修饰的类、方法、变量时会提示相应的警告信息。
Override 注解
指明被注解的方法需要覆写超类中的方法,如果某个方法使用了该注解,却没有覆写超类中的方法(如大小写写错了,或者参数错了,或者是子类自己定义的方法),编译器就会生成一个错误。
在子类中重写父类或接口的方法,@Overide并不是必须的。但是还是建议使用这个注解,在某些情况下,假设你修改了父类的方法的名字,那么之前重写的子类方法将不再属于重写,如果没有@Overide,你将不会察觉到这个子类的方法。有了这个注解修饰,编译器则会提示你这些信息。
Suppresswarnings 注解
@SuppressWarnings用来抑制编译器生成警告信息,可以修饰的元素为类,方法,方法参数,属性,局部变量。它可以达到抑制编译器编译时产生警告的目的,使用@SuppressWarnings注解,采用就近原则,比如一个方法出现警告,尽量使用@SuppressWarnings注解这个方法,而不是注解方法所在的类。所属范围越小越好,因为范围大了,不利于发现该类下其他方法的警告信息。
但是很不建议使用@SuppressWarnings注解,使用此注解,开发人员看不到编译时编译器提示的相应的警告,不能选择更好、更新的类、方法或者不能编写更规范的编码。同时后期更新JDK、jar包等源码时,使用@SuppressWarnings注解的代码可能受新的JDK、jar包代码的支持,出现错误,仍然需要修改。
2、 注解的创建
package main.java.com.nf147.annot; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Animal { String name() default ""; String sex() default "公"; int age() default 0; // 1. 创建的语法跟接口非常像 // 2. 可以通过 default 语句给与默认值 }
3、注解的使用
1. 首先,在需要的地方,添加注解
package com.nf147.ioc; import com.nf147.annot.Animal; @Animal(name = "伊丽莎白", sex = "母", age = 1) public class Dog { public void introduce(){ System.out.println("大家好,我是伊丽莎白"); } }
2. 通过反射获取注解信息
三个重要的方法:
- isAnnotationPresent()
- getAnnotation()
- getAnnotations()
package com.nf147.web; import com.nf147.annot.Animal; import com.nf147.ioc.Dog; import org.junit.Test; public class DogTest { @Test public void dogTest(){ Class dogClass = Dog.class; if (dogClass.isAnnotationPresent(Animal.class)) { Animal anno = (Animal) dogClass.getAnnotation(Animal.class); String name = anno.name(); String sex = anno.sex(); int age = anno.age(); System.out.println("我是"+name+",今年"+age+"岁"); } } }