本节内容:
1.认识Annotation
2.系统定义的Annotaion
3.自定义Annotaion
4.Retention和RetentionPolicy
5.反射与Annotaion
6@Documented
7@Target注解
8@Inherited注解
一.认识Annotation
在jdk1.5开始,java新增了对元数据(类的组成单元数据)的支持也就是(Annotation)注解,他就是代码中的特殊标记,这些标记可以在编译、类加载,运行时在不改变原有逻辑的情况下,被读取,并执行相应的处理,通过使用Annotation,程序员可以在源文件中嵌入一些补充信息。Annotation类似于修饰符一样被使用,可以用于包、类、构造方法、方法、成员变量、参数、局部变量的声明。
注意:Annotaion是一个接口,在java.lang包下。
二、系统定义的Annotaion
在jdk1.5之后,系统中提供了3个Annotaion:分别是:@Override 、@Deprecated、@SuppressWarnings ()
@Override:表示当前的方法定义将覆盖超类中的方法,如果不小心些错误,或者方法名对不上,被覆盖的方法,编译器就会出现错误提示
@Deprecated:表示的是一个或者方法已经不在建议使用,标记为已过时。
@SuppressWarnings ()
表示关闭不当的编译器警告信息
三、自定义Annotation
注解应用需要三个步骤:
1.编写注解
2.在类上应用注解
3.对应用了注解的类进行反射操作的类
自定义Annotation的语法;
访问控制权限@interface Annotation 名称{}
例如:
public @interface MyAnnotation{
}
package com.wuzhilong; /** * 自定义注解 */ public @interface MyAnnotation { // 定义变量 public String name(); //给属性设置默认值:在使用的时候就不是必须传值 public int age() default 2; // 定义数组类型 public String[] like(); // 定义枚举类型 public Color[] color(); }
package com.wuzhilong; /** * 使用注解 */ @MyAnnotation (name="小明",age=4,like = {"篮球","足球"},color = Color.GREED) public class Dog { private String name; private int age; private 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; } public Color getColor() { return color; } public void setColor(Color color) { this.color = color; } }
package com.wuzhilong; /** * 枚举 */ public enum Color { RED,GREED,YELLOW; }
四、Retention和RetentionPolicy
Annotation想要决定其作用的范围,通过@Retention指定,而Retention指定的范围由RetentionPolicy决定,RetentionPolicy指定了三种范围:
范围 | 描述 |
public static RetentionPolicy SOURCE | 在java源文件中存在 |
public static RetentionPolicy CLASS | 在java生成的class中存在 |
public static RetentionPolicy RUNTIME | 在java运行的时候存在 |
示例:
/** * 自定义注解 */
//设置注解的使用范围
@Retention (RetentionPolicy.RUNTIME) public @interface MyAnnotation { // 定义变量 public String name(); //给属性设置默认值:在使用的时候就不是必须传值 public int age() default 2; // 定义数组类型 public String[] like(); // 定义枚举类型 public Color[] color(); }
五、反射与Annotaion
一个Annotation想要真正起作用,必须结合反射机制,在反射中提供了以下操作方法:
java.lang.reflect.AccessibleObject
方法名称 | 描述 |
public boolean isAnnotationPresent(Class<? extends Annotation> AnnotationClass) | 判断是否是指定的Annotation |
public Annotation[] getAnnotation() | 得到全部的Annotation |
package com.wuzhilong; import java.lang.annotation.Annotation; public class Test { public static void main(String[] args) { Class<Dog> dogClass = Dog.class; //获取类上的指定的注解 MyAnnotation annotations = dogClass.getAnnotation(MyAnnotation.class); // 获取注解上的变量值 String name = annotations.name (); int age = annotations.age (); String[] like = annotations.like (); Color[] color = annotations.color (); try { Dog dog = dogClass.newInstance (); dog.setName (name); dog.setAge (age); dog.setColor (color); System.out.println (dog); }catch (Exception e){ } } }
六、@Documented
Documented 注解表明这个注解应该被 javadoc工具记录. 默认情况下,javadoc是不包括注解的. 但如果声明注解时指定了 @Documented,则它会被 javadoc 之类的工具处理, 所以注解类型信息也会被包括在生成的文档中.
七、@Target注解
@Target注解表示的是一个Annotation的使用范围,如果没有这个注解,name这个注解就可以使用在任何位置
ElementType 这个枚举类型的常量提供了一个简单的分类:注释可能出现在Java程序中的语法位置(这些常量与元注释类型(@Target)一起指定在何处写入注释的合法位置)
package java.lang.annotation; /** * The constants of this enumerated type provide a simple classification of the * syntactic locations where annotations may appear in a Java program. These * constants are used in {@link Target java.lang.annotation.Target} * meta-annotations to specify where it is legal to write annotations of a * given type. * @author Joshua Bloch * @since 1.5 * @jls 9.6.4.1 @Target * @jls 4.1 The Kinds of Types and Values */ public enum ElementType { /** 类, 接口 (包括注释类型), 或 枚举 声明 */ TYPE, /** 字段声明(包括枚举常量) */ FIELD, /** 方法声明(Method declaration) */ METHOD, /** 正式的参数声明 */ PARAMETER, /** 构造函数声明 */ CONSTRUCTOR, /** 局部变量声明 */ LOCAL_VARIABLE, /** 注释类型声明 */ ANNOTATION_TYPE, /** 包声明 */ PACKAGE, /** * 类型参数声明 * * @since 1.8 */ TYPE_PARAMETER, /** * 使用的类型 * * @since 1.8 */ TYPE_USE }
八、@Inherited注解
@Inherited:允许子类继承父类的注解。
Inherited作用是,使用此注解声明出来的自定义注解,在使用此自定义注解时,如果注解在类上面时,子类会自动继承此注解,否则的话,子类不会继承此注解。这里一定要记住,使用Inherited声明出来的注解,只有在类上使用时才会有效,对方法,属性等其他无效。