JDK1.5开始,Java增加了对元数据(即类的组成单元数据)的支持,也就是( Annotation)
注解,他是代码里做的特殊标记,这些标记可以在编译,类加载,运行时在不改变原有
逻辑的情况下,被读取,并执行相应的处理,通过使用Annotation,程序员可以在源文
件中嵌入一些补充的信息。代码分析工具,开发工具和部署工具可以通过这些补充信息
进行验证或者进行部署。Annotation类似于修饰符一样被使用, 可以用于包,类,构造
方法,方法,成员变量,参数,局部变量的声明。
注意:
Annotation是一一个接口
java.lang.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")
//全部类型的警告
自定义注解:
注解应用需要三个步骤:
(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();
}
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:
在java运行的时候存在
示列:
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
public String name();
}
反射与Annotation
一个Annotation真正起作用,必须结合反射机制,在反射中提供了以下的操作方法:java.lang.reflect.AccessibleObject
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
判断是否是指定的Annotation
public Annotation[] getAnnotations()
得到全部的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);
}
@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";
}
@Target注解
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
只能在包中使用
@Inherited注解
@Inherited表示一个Annotation是否允许被其子类继承下来。
示例
@Inherited
@Target(value = ElementType.TYPE)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
public String name();
public String info();
}
使用时允许被其子类所继承。