Java必备:基本Annotation
一、Annotation简介
-
从Java1.5开始,Java增加了元数据(MetaData)的支持,也就是Annotation(注释);
-
Annotation能被用来为程序元素(类、方法、成员变量等)设置元数据;
-
Annotation不能影响程序代码的执行,无论添加、删除Annotation,代码始终如一的执行;
-
如果希望让程序中的Annotataion能在 运行时其一定作用,只有通过某种配套的工具对Annotation中的信息进行访问和处理,这些工具统称APT(Annotion Processing Tool);
二、三个基本的Annotation如下:
-
@Override:限定重写父类方法
-
用来指定方法覆盖的,它可以强制一个子类必须要覆盖父类的方法;
-
只能用作于方法,不能用于作用其他程序元素;
-
主要是帮助我们避免一些低级错误;
-
<span style="font-size:18px;"><span style="font-family:SimSun;">public class Fruit {
public void foo(){
System.out.println("水果的info方法。。。");
}
}
class Apple extends Fruit
{
//使用@Override指定下面方法必须重写父类方法
@Override
public void foo() {
System.out.println("苹果重写水果的info方法...");
}
} <span style="color:windowtext;line-height: 15px; background-color: transparent;"> </span></span></span>
-
@Deprecated:标记已过时
-
用于标识某个程序元素(类、方法等)已过时,当其他程序使用已过时的类、方法时,编译器将会给出警告;
-
<span style="font-family:SimSun;font-size:18px;">class Apple1{
//定义info方法已经过时
@Deprecated
public void info(){
System.out.println("Apple的info方法");
}
}
public class DeprecatedTest {
public static void main(String[] args) {
//下面使用info方法时将会被编译器警告
new Apple1().info();
}
} </span>
-
@SuppressWarnings:抑制编译器警告
-
指示被Annotation标识的程序元素(以及在该程序元素中的所有字元素)取消显示指定的编译器警告;
-
一直作用于该程序元素的所有子元素;
-
//关闭整个类里的编译器警告
@SuppressWarnings(value="unchecked")
public class SuppressWarningsTest {
public static void main(String[] args) {
List<String> myList = new ArrayList();
myList.add("java");
}
}
三、JDK的Annotation
一、使用@Retention
-
只能修饰一个Annotation定义,用于指定该Annotation可以保留多长时间;
-
包含一个RetentionPolicy类型的value成员变量:
-
RetentionPolicy.CLASS:编译器把注释记录在class文件中,当运行Java程序时,JVM不在保留注释,默认值;
-
RetentionPolicy.RUNTIME:编译器将把注释记录在class文件中,当运行Java程序时,JVM也会保留注释,程序可以通过反射获取该注释;
-
RetentionPolicy.SOURCE:编译器直接丢弃这种策略的注释;
-
注意:interface 是接口 @interface是自定义的annotation
//定义下面的Testable注解保留到运行时
@Retention(value="RetentionPolicy.RUNTIME")
public @interface Testable{}
二、使用@Target
-
用于修饰一个Annotation定义,指定被修饰的Annotation能用于修饰哪些程序元素;
-
包含一个名为value的成员变量:
-
ElementType.ANNOTATION_TYPE:只能修饰Annotation;
-
ElementType.CONSTRUCTOR:只能修饰构造器;
-
ElementType.FIELD:只能修饰成员变量;
-
ElementType.LOCAL_VARIABLE:只能修饰局部变量;
-
ElementType.METHOD:只能修饰方法定义;
-
ElementType.PACKAGE:只能修饰包定义;
-
ElementType.PARAMETER:只能修饰参数;
-
ElementType.TYPE:只能修饰类、接口(包括注释型)或枚举定义;
-
//定义下面的ActionListenerFor注解只能用于成员变量
@Target(ElementType.FIELD)
public @interface ActionListenerFor{};
三、使用@Documented
-
用于指定该元Annotation修饰的Annotation类将被javadoc工具提取成文档;
@Retention(value="RetentionPolicy.RUNTIME")
@Target(ElementType.METHOD)
//定义下面的Testable注解将被javadoc提取
@Documented
public @interface Testable{}
使用@Inherited
-
指定它修饰的Annotation将具有继承性;
-
如果某个类使用了A Annotation(定义该Annotation使用了@Inherited修饰)修饰,则其子类将自动具有A注释;
四、自定义Annotation步骤
-
使用@interface关键字定义新的Annotation
//定义一个简单的Annotation类型
public @interface Test{
}
-
用于修饰程序的类、方法、变量、接口等定义
//使用@Test修饰类定义
@Test
public class MyClass{
}
public class MyClass{
//使用@TestAnnotaion修饰方法
@Test
public void info(){
}
}
-
定义Annotation成员变量
public @interface MyTag{
//定义两个成员变量的Annotation
//Annotation中的成员变量以方法的形式定义
String name();
int age();
}
-
使用该Annotation时,为该Annotation的成员变量指定值
public class Test{
//使用成员变量的Annotation时,需要为成员变量指定值
@MyTag(name="xx",age=6)
public void info(){
…
}
...
} <span style="color: windowtext; line-height: 15px; font-family: Calibri, sans-serif; font-size: 10pt; background-color: transparent;"> </span>
-
我们还可以为Annotation指定初始值,使用default关键字
public @interface MyTag{
//定义两个成员变量的Annotation
//以default为两个成员变量指定初始值
String name() default "yeeku";
int age() default 32;
}
-
如果为Annotation的成员变量指定了默认值,使用时则可以不为这些成员变量指定值;
-
当然,如果为MyTag的成员变量指定了值,则默认值不会起作用;
二、Annotation分类
-
根据Annotation是否包含成员变量,我们可以把Annotation分为如下两类:
-
标记Annotation:没有成员定义,仅使用自身存在与否来为我们提供信息;
-
元数据Annotation:包含成员变量;
-
三、提取Annotation的信息
-
Annotatoin不会自己生效,必须由开发者提供相应的工具来提取并处理Annotation信息;
-
当一个Annotaion类型被定义为运行时Annotaion后,该Annotation才会在运行时可见,JVM才会装载*.class文件时读取保存在class文件中的Annotation;
-
Annotaion接口:代表程序元素前面的注释;
-
AnnotatedElement接口:代表程序中可以接受注释的程序元素;
-
主要有如下几个实现类:Class,Constructor,Field,Method,Package;
-
通过反射获取某个类的AnnotatedElement对象,调用该对象的如下方法访问Annotataion信息;
-
getAnnotation(Class<T> annotationClass):返回该程序上存在的制定类型的注释,如果该类型的注释不存在,则返回null;
-
Annotation[] getAnnotations():返回该程序元素上所存在的所有注释;
-
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass):判断该程序元素上是否存在指定类型的注释,如果存在返回true,否则返回false;
-
-