1、 认识Annotation
JDK1.5开始, Java增加了对元数据(即类的组成单元数据) 的支持, 也就是(Annotation)注解, 他是代码里做的特殊标记, 这些标记可以在编译, 类加载, 运行时在不改变原有逻辑的情况下, 被读取, 并执行相应的处理, 通过使用Annotation, 程序员可以在源文件中嵌入一些补充的信息。 代码分析工具, 开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。
Annotation类似于修饰符一样被使用, 可以用于包, 类, 构造方法, 方法, 成员变量, 参数, 局部变量的声明。
注意:
Annotation是一个接口
java.lang.Annotation接口
注解的本质是标记,他所有的功能都依赖于对于这个给注解解释性的代码,通常需要结合反射来编写解释性代码。
2、 系统定义的Annotation
在JDK 1.5之后, 在系统中提供了三个Annotation, 分别是: @Override、 @Deprecated、 @SuppressWarnings。
@Override
表示当前的方法定义将覆盖超类中的方法。 如果你不小心拼写错误, 或者方法签名对不上被覆盖的方法, 编译器就会发出错误提示。
@Deprecated
表示的是一个类或方法已经不再建议继续使用了, 标记为已过时。
@SuppressWarnings
表示关闭不当的编译器警告信息。
- @SuppressWarnings(“unchecked”)//未检查的转化, 如集合没有指定类型
- @SuppressWarnings(“unused”) //未使用的变量
- @SuppressWarnings(“resource”) //有泛型未指定类型
- @SuppressWarnings(“path”) //在类路径, 原文件路径中有不存在的路径
- @SuppressWarnings(“deprecation”) //使用了某些不赞成使用的类和方法
- @SuppressWarnings(“fallthrough”) //switch语句执行到底没有break关键字
- @SuppressWarnings(“serial”)//某类实现Serializable 但是没有定义serialVersionUID 这个需要但是不必须的字段
- @SuppressWarnings(“rawtypes”) //没有传递带有泛型的参数
- @SuppressWarnings(“all”) //全部类型的警告
3、 自定义Annotation
注解应用需要三个步骤:
(1) 编写注解
(2) 在类上应用注解
(3) 对应用了注解的类进行反射操作的类
自定义Annotation的语法如下:
访问控制权限 @interface Annotation名称{}
例如:
public @interface MyAnnotation {}
在Annotation中定义变量
public @interface MyAnnotation {public String name();public String info();}
定义变量后, 在调用此Annotation时必须设置变量值。
@MyAnnotation(name = "vince", info = "hello")public class Demo {}
通过default指定变量默认值,有了默认值在使用时可以不设值
public @interface MyAnnotation {public String name() default "vince";public String info() default "hello";}
定义一个变量的数组, 接收一组参数
public @interface MyAnnotation {public String[] name();}
使用时指定数组值
@MyAnnotation(name = { "jack", "vince" })public class Demo {}
使用枚举限制变量取值范围
public enum Color {RED, GREEN, BLUE}public @interface MyAnnotation {public Color color();}
4、 Retention和RetentionPolicy
Annotation要想决定其作用的范围, 通过@Retention指定, 而Retention指定的范围由
RetentiontPolicy决定, RetentionPolicy指定了三种范围:
| 范围 | 描述 |
|---|---|
| public static final RetentionPolicy SOURCE | 在java源程序中存在 |
| public static final RetentionPolicy CLASS | 在java生成的class中存在 |
| public static final RetentionPolicy RUNTIME | 在运行的时候存在 |
@Retention(value = RetentionPolicy.RUNTIME)public @interface MyAnnotation {public String name();}
5、反射与Annotation
Class<?> cls = Class.forName("com.vince.annotation.Test");Method met = cls.getMethod("setName"); // 找到setName()方法if (met.isAnnotationPresent(MyAnnotation.class)) {MyAnnotation my = (MyAnnotation) met.getAnnotation(MyAnnotation.class);String name = my.name();String info = my.info();System.out.println("name = " + name);System.out.println("info = " + info);}
6、 @Documented注解
此注解表示的是文档化, 可以在生成doc文档的时候添加注解。
@Documented@Retention(value = RetentionPolicy.RUNTIME)public @interface MyAnnotation {public String name();public String info();}
可以增加一些DOC注释。
/*** 这个方法是从Object类中覆写而来的*/@MyAnnotation(name = "vince", info = “teacher")public String toString() {return "hello";}
7、 @Target注解
@Target注解表示的是一个Annotation的使用范围, 例如: 之前定义的MyAnnotation可以在任意的位置上使用。
| 范围 | 描述 |
|---|---|
| public static final ElementType TYPE | 只能在类或接口或枚举上使用 |
| public static final ElementType FIELD | 在成员变量使用 |
| public static final ElementType METHOD | 在方法中使用 |
| public static final ElementType PARAMETER | 在参数上使用 |
| public static final ElementType CONSTRUCTOR | 在构造中使用 |
| public static final ElementType LOCAL_VARIABLE | 局部变量上使用 |
| public static final ElementType ANNOTATION_TYPE | 只能在Annotation中使用 |
| public static final ElementType PACKAGE | 只能在包中使用 |
8、 @Inherited注解
@Inherited表示一个Annotation是否允许被其子类继承下来。
示例
@Inherited@Target(value = ElementType.TYPE)@Retention(value = RetentionPolicy.RUNTIME)public @interface MyAnnotation {public String name();public String info();}
Cat
import java.util.Arrays;/***/@MyAnnotation(name = "bin",like = {"金鱼","鲫鱼","鲤鱼"},color = Color.GREEN)public class Cat {private String name;private int age;private Color color;private String[] like;public String[] getLike() {return like;}public void setLike(String[] like) {this.like = like;}public Color getColor() {return color;}public void setColor(Color color) {this.color = color;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}//用于验证方法是否覆盖父类中的方法@Overridepublic String toString() {return "Cat{" +"name='" + name + '\'' +", age=" + age +", color=" + color +", like=" + Arrays.toString(like) +'}';}//用于标记方法已过时,不建议使用@Deprecatedpublic String printInfo(){return "Cat{" +"name='" + name + '\'' +", age=" + age +'}';}public Cat() {}public Cat(String name, int age) {this.name = name;this.age = age;}}
MyAnnotation
import java.lang.annotation.*;/*** 自定义注解*///用于生成文档@Documented//表示该注解的作用范围在运行时存在@Retention(RetentionPolicy.RUNTIME)//用于表示注解的应用范围(类型,方法,属性,构造器,参数,局部变量,包,Annotation)@Target(ElementType.TYPE)@Inheritedpublic @interface MyAnnotation {//定义变量public String name();public int age() default 2; //给变量设置默认值public String[] like();//定义一个数组变量public Color color();//定义一个枚举类型的变量}
AnnotationDemo
import org.junit.Test;import java.util.ArrayList;import java.util.List;//消除警告信息@SuppressWarnings("all")public class AnnotationDemo {//反射来处理注解@Testpublic void test2(){Class<Cat> catClass = Cat.class;//获取类上应用的指定注解MyAnnotation annotation = catClass.getAnnotation(MyAnnotation.class);//获取注解上变量值String name = annotation.name();int age = annotation.age();Color color = annotation.color();String[] like = annotation.like();try {Cat cat = catClass.newInstance();cat.setName(name);cat.setAge(age);cat.setLike(like);cat.setColor(color);System.out.println(cat);} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}@Testpublic void test1(){Cat cat = new Cat("miaomiao",3);cat.printInfo();//调用了一个已过时的方法List list = new ArrayList();list.add("vince");list.add(10);list.add(10.1f);}}
Color
/***/public enum Color {RED,GREEN,YELLOW;}
