JDK1.5开始,Java增加了对元数据(即类的组成单元数据)的支持,也就是(Annotation)注解,他是代码里做的特殊标记,这些标记可以在编译,类加载,运行时在不改变原有逻辑的情况下被读取,并执行相应的处理,通过使用Annotation,程序员可以在源文件中嵌入一些补充的信息。代码分析工具,开发工具和部署工具可以通过这些补充信息进行验证或者进行部署,Annotation类似于修饰符一样被使用,可以用于包、类、构造方法、方法、成员变量、参数、局部变量的声明。
PS:Annotation是一个接口(Java.lang.Annotation接口)
在JDK1.5之后,在系统中提供了三个Annotation,分别是:@Override
,@Deprecated
,@SuppressWarnings
表示当前方法定义将重写父类中的方法,如果不小心拼写错误,或者方法名对不上重写的方法,编译器就会发出错误提示。
重写Object中的toString方法,只要重写方法有问题,就有错误提示
用于表示所修饰的元素(类,方法,构造器,属性等)已过时,但是该方法也能使用
抑制编译器警告
@SuppressWarnings("unchecked")
:未检查的转化,如集合没有指定类型@SuppressWarnings("unused")
:未使用的变量@SuppressWarnings("resource")
:有泛型未指定类型@SuppressWarnings("path")
:在类路径,原文件路径中不存在的路径@SuppressWarnings("deprecation")
:使用了某些不赞成使用的类的方法@SuppressWarnings("fallthrough")
:switch语句中执行到底没有break关键字@SuppressWarnings("serial")
:某类实现Serializable但是没有定义SerialVersionUID这个需要但是不必须的字段@SuppressWarnings("rawtypes")
:没有传递带有泛型的参数@SuppressWarnings("all")
:全部类型的警告
自定义注解使用很少,一般情况下都是用现成的注解。
注解应用需要三个步骤:
- 编写注解
- 在类上应用注解
- 对应用了注解的类进行反射操作的类
定义的注解的声明使用的关键字:@interface,跟接口没有一点关系
这value是属性还是方法?
答案:看上去是无参数方法,实际上理解为一个成员变量,一个属性
无参数方法名字–>成员变量的名字
无参数方法的返回值–>成员变量的类型
这个参数叫配置参数
无参数方法的类型:基本数据类型(八种),String,枚举,注解类型,还可以是以上类型对应的数组。
使用注解的话,如果你定义了配置参数,就必须给配置参数进行赋值操作
如果只有一个参数,并且这个参数的名字为value的话,那么value=可以省略不写
如果你给配置参数设置默认的值了,那么使用的时候可以无需传值
一个注解的内部是可以不定义配置参数的,内部没有定义配置参数的注解–>可以叫做标记
内部定义配置参数的注解–>元数据
一个
Annotation
真正起作用,必须结合反射机制,在反射包(java.lang.reflect.AccessibleObject
)中提供了以下的操作方法:
public boolean isAnnotationPresent(Class extends Annotation>)
:判断是否指定的Annotationpublic Annotation[] getAnnotations()
:得到全部的Annotation
public class Test {
public static void main(String[] args) {
//反射来处理注解
Class<Person> personClass = Person.class;
//获取类变量上的指定注解
MyAnnotation annotation = personClass.getAnnotation(MyAnnotation.class);
//获取注解的变量值
String[] value = annotation.value();
}
}
JDK1.5提供了四种元注解:Retention, Target, Documented, Inherited
@Retention
:用于修饰注解,用于指定修饰的那个注解的生命周期,@Rentention包含一个RetentionPolicy枚举类型的成员变量,使用@Rentention时必须为该value成员变量指定值
RetentionPolicy.SOURCE
:在源文件中有效(即源文件保留),编译器直接丢弃这种策略的注释,在.class文件中不会保留注解信息RetentionPolicy.CLASS
:在class文件中有效(即class保留),保留在.class文件中,但是当运行Java程序时,他就不会继续加载了,不会保留在内存中,JVM不会保留注解。如果注解没有加Retention元注解,那么相当于默认的注解就是这种状态。RetentionPolicy.RUNTIME
:在运行时有效(即运行时保留),当运行 Java程序时,JVM会保留注释,加载在内存中了,那么程序可以通过反射获取该注释。@Target注解表示的是一个Annotation的使用范围,例如:之前定义的MyAnnotation可以在任意的位置上使用
@Target({TYPE,CONSTRUCTOR,METHOD})
public @interface MyAnnotation4 {
}
用于指定被该元注解修饰的注解类将被javadoc工具提取成文档。默认情况下,javadoc是 不包括注解的,但是加上了这个注解生成的文档中就会带着注解了
如果:Documented注解修饰了Deprecated注解
那么Deprecated注解就会在javadoc提取的时候,提取到API中
被他修饰的Annotation将具有继承性,如果某个类使用了被@Inherited修饰的Annotation,则其子类将自动具有该注解
使用时允许被其子类所继承
@Inherited
@Target(value = ElementType.TYPE)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation{
public String name();
public Striing info();
}