主要内容
详细内容
了解注解以及四种基本注解
概述
public interface Annotation
注解是一个接口,程序可以通过反射来获取指定程序元素的注解对象;
该接口有四个常用方法:
(1)Class<? extends Annotation> annotationType() :返回此注解的注释类型;
(2)boolean equals(Object obj) :如果指定的对象表示在逻辑上等效于此接口的注释,则返回true;
(3)int hashCode() :返回此注解的哈希码;
(4)String toString() :返回此注解的字符串表示形式。
@Override:限定重写父类方法
@Target(value=METHOD)
@Retention(value=SOURCE)
public @interface Override
@Overrride用来指定方法覆载的,它可以强制一个子类必须覆盖父类的方法。
示例代码如下所示:
public class Animal
{
public void communicate()
{
System.out.println("动物都会交流!");
}
}
class Dog extends Animal
{
// 使用@Override指定子类必须重写父类方法
@Override
public void communicate()
{
System.out.println("狗狗是通过汪汪进行交流!");
}
}
@Override只能作用于方法,不能作用于其它元素。
@Deprecated:标示已过时
@Documented
@Retention(value=RUNTIME)
public @interface Deprecated
@Deprecated用于表示某个程序元素(类或者方法等)已经过时,当其他程序使用已过时的类或方法时,编译器会发出警告。
在eclipse中会使用下划线在该方法下面标识该方法为过时方法,如下图所示:
在命令行中运行如下所示:
@SuppressWarning:抑制编译器警告
@Target(value={TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})
@Retention(value=SOURCE)
public @interface SuppressWarnings
@SuppressWarning指示被该Annotation修饰的程序元素以及该程序元素中的所有子元素取消现在是指定的编译器警告。
//关闭整个类中的编译器警告
@SuppressWarnings(value = "unchecked")
public class SuppressWarningsTest
{
@SuppressWarnings("deprecation")
public static void main(String[] args)
{
System.runFinalizersOnExit(true);
}
}
@SafeVarargs
@Documented
@Retention(value=RUNTIME)
@Target(value={CONSTRUCTOR,METHOD})
public @interface SafeVarargs
当把一个不带泛型的对象赋值给一个带泛型的变量时,就会发生“堆污染”。
可以使用以下三种方式来“抑制”这个警告。
(1)使用@SafeVarargs修饰引发该警告的犯法或者构造器;
(2)使用@SuppressWarnings(value = "unchecked")修饰;
(3)编译的时候使用-Xlint:varargs选项。
JDK的元注解
@Retention
@Retention只能用于修饰一个Annotation定义,用于指定被修饰的Annotation可以保留多长时间,@Retention中包含一个RetentionPolicy类型的value成员变量,在使用@Rentention时必须为该value成员变量指定值。
Value成员变量的值只能是如下三个:
(1)RetentionPolicy.CLASS:编译器将把Annotation记录在class文件当中,当运行Java程序时,JVM将不再保留Annotation,这是默认值;
(2)RetentionPolicy.RUNTIME:编译器把Annotation记录在class文件当中,当运行Java程序时,JVM会保留Annotation,程序可以通过反射获取该Annotation信息;
(3)RetentionPolicy.SOURCE:Annotation只保留在源代码中,编译器直接丢弃这种Annotation。
@Target
格式如下所示:
@Target(ElementType.ANNOTATION_TYPE)
public @interface MetaAnnotationType {
...
}
@Target也只能修饰一个Annotation定义,它用于指定被修饰的Annotation能用于修饰哪些程序单元。@Target中包含value成员变量,该成员变量的值如下所示:
(1)ANNOTATION_TYPE :注释类型声明
(2)CONSTRUCTOR:构造方法声明
(3)FIELD :字段声明(包括枚举常量)
(4)LOCAL_VARIABLE局部变量声明
(5)METHOD 方法声明
(6)PACKAGE 包声明
(7)PARAMETER 参数声明
(8)TYPE 类、接口(包括注释类型)或枚举声明
@Documented
@Documented用于指定被该元注解修饰的注解类将被javadoc工具提取成文档,如果定义Annotation类时使用了@Documented修饰,则所有使用该Annotation修饰的程序元素的API文档中都将包含该Annotation说明。
@Inherited
@Inherited元Annotation指定被它修饰的Annotation将具有继承性,如果一个了使用的注解被@Inherited修饰的话,则其子类也将自动被该注解所修饰。
自定义注解以及应用
定义注解
定义一个新的注解类型使用@Interface关键字来实现。
元注解以及其枚举属性值不用记,只要会看jdk提供那几个基本注解的API帮助文档的定义或其源代码,按图索骥即可查到,或者直接看java.lang.annotation包下面的类。
增加基本属性
注解的属性定义
一个注解相当于一个胸牌,如果你胸前贴了胸牌,就是传智播客的学生,否则,就不是。如果还想区分出是传智播客哪个班的学生,这时候可以为胸牌在增加一个属性来进行区分。加了属性的标记效果为:@MyAnnotation(color="red")
如何定义?
(1)定义基本类型的属性和应用属性:
在注解类中增加String color();
@MyAnnotation(color="red")
(2)用反射方式获得注解对应的实例对象后,再通过该对象调用属性对应的方法
MyAnnotation a = (MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
System.out.println(a.color());
可以认为上面这个@MyAnnotation是MyAnnotaion类的一个实例对象
为属性指定缺省值:
String color() default "yellow";
value属性:
String value() default "zxx";
如果注解中有一个名称为value的属性,且你只想设置value属性(即其他属性都采用默认值或者你只有一个value属性),那么可以省略value=部分,例如:@MyAnnotation("lhm")。
增加高级属性
(1)数组类型的属性
int [] arrayAttr() default {1,2,3};
@MyAnnotation(arrayAttr={2,3,4})
如果数组属性中只有一个元素,这时候属性值部分可以省略大括号。
(2)枚举类型的属性
EnumTest.TrafficLamp lamp() ;
@MyAnnotation(lamp=EnumTest.TrafficLamp.GREEN)
(3)注解类型的属性:
MetaAnnotation annotationAttr() default @MetaAnnotation("xxxx");
@MyAnnotation(annotationAttr=@MetaAnnotation(“yyy”) )
可以认为上面这个@MyAnnotation是MyAnnotaion类的一个实例对象,同样的道理,可以认为上面这个@MetaAnnotation是MetaAnnotation类的一个实例对象,调用代码如下:
MetaAnnotation ma = myAnnotation.annotationAttr();
System.out.println(ma.value());
示例代码如下所示:
//元注解
@Target( { ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface ItcastAnnotation
{
String color() default "blue";
String value();
int[] arrayAttr() default { 3, 4, 5 };
MetaAnnotation annotationAttr() default @MetaAnnotation("1hm");
}
@ItcastAnnotation(annotationAttr = @MetaAnnotation("hwb"), color = "red", value = "hwb", arrayAttr = 23)
public class AnnotationTest
{
@ItcastAnnotation("xyz")
public static void main(String[] args) throws Exception
{
if (AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class))
{
ItcastAnnotation annotation = AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
// 获取元注解中的color值
System.out.println("元注解中的color值 : " + annotation.color());
// 获取元注解中的value值
System.out.println("元注解中的value值 : " + annotation.value());
// 获取元注解中的arrayAttr的长度值
System.out.println("元注解中的arrayAttr的长度值 : " + annotation.arrayAttr().length);
// 获取元注解中的arrayAttr中的属性值
System.out.println("元注解中的arrayAttr中的属性值 : " + annotation.annotationAttr().value());
}
}
}
运行结果如下所示: