Annotation(注解)

来源:互联网 发布:淘宝店铺动态评分计算 编辑:程序博客网 时间:2024/05/21 22:24


注解就相当于一个你的源程序中要调用的一个类,要在源程序中应用某个注解,得先准备好了这个注解类。就像你要调用某个类,得先有开发好这个类。注解就相当于一个标记,加了注解就等于打上了某种标记,没加等于没有某种标记,以后javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无各种标记,根据你有无某种标记,做出相应的动作。标记可以加在包上,类,字段,方法,方法的参数及局部变量上。

Sun提供的三个注解

@SuppereddWarnings压缩警告

@Override说明此方法是复写了父类的方法,可以用来判断是否复写了父类的方法,如果为复写报错

@Deprecated 表明已过时

 

注解的应用结构图

注解的定义域接口的定义类似,自定义注解:

package liaoli.review2;

 

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

 

@Retention(RetentionPolicy.RUNTIME)

public @interface LiaoliAnnotation {

 

}

 

将自定义类加在类上,并通过反射或取此注解

package liaoli.review2;

 

@LiaoliAnnotation

public class AnnotationTest {

 

   

    public static void main(String[] args) {

       Class clazz = AnnotationTest.class;

      

       //判断类上是否存在某个注解

       System.out.println(clazz.isAnnotationPresent(LiaoliAnnotation.class));

       //获取类的某个注解

       LiaoliAnnotation annotation = (LiaoliAnnotation)clazz.getAnnotation(LiaoliAnnotation.class);

      

       System.out.println(annotation.annotationType());

    }

 

}

运行结果:

true

interface liaoli.review2.LiaoliAnnotation

发现如果自定义注解如果不加上@Retention(RetentionPolicy.RUNTIME)的话运行出现异常,且clazz.isAnnotationPresent(LiaoliAnnotation.class)的值为false这是为什么呢?

    因为@Retention为源注解,所谓源注解就注解的注解源注解有一个枚举类型的属性RetentionPolicy,此枚举可以取三个值,这三个值分别表示,注解生命期

SOURCE   ---àjava源文件,

CLASS    ---àclass文件,

RUNTIME ---à内存中的字节码文件。

而默认的注解生命期为CLASS    ---àclass文件,所以如果不写@Retention(RetentionPolicy.RUNTIME)的话注解值保存到编译完的Class中,当累加载器将class文件加载如内存时,就将注解去掉了,所以就会出现以上运行结果了

    Target也是一个源注解,Target的属性为ElementType的一个枚举类型,他表示的是注解应该标注在什么位置,Target可以传入多个参数,它的值可取为:

 

TYPE   表示可以在类、接口(包括注释类型)或枚举声明 

 

FIELD   字段声明(包括枚举常量) 

 

METHOD  方法声明 

 

PARAMETER  参数声明 

 

CONSTRUCTOR  构造方法声明 

 

LOCAL_VARIABLE 局部变量声明 

 

ANNOTATION_TYPE 注释类型声明 

 

PACKAGE 包声明 
 
一个注解相当于一个胸牌,如果你胸前贴了胸牌,就是黑马的学生,否则,就不是。如果还想区分出是黑马哪个班的学生,这时候可以为胸牌增加一个属性来进行区分。加了属性的标记效果为:@ LiaoliAnnotation (color="red")
用反射方式获得注解对应的实例对象后,再通过该对象调用属性对应的方法
LiaoliAnnotation a = (LiaoliAnnotation)AnnotationTest.class.getAnnotation(LiaoliAnnotation.class);
System.out.println(a.color()); 
可以认为上面这个@ LiaoliAnnotation是LiaoliAnnotation类的一个实例对象
 
为属性指定缺省值:
String color() default "yellow";
value属性: 
String value() default "zxx"; 
如果注解中有一个名称为value的属性,且你只想设置value属性(即其他属性都采用默认值或者你只有一个value属性),那么可以省略value=部分,例如:@LiaoliAnnotation("lhm")。 
 
数组类型的属性
int [] arrayAttr() default {1,2,3};
@LiaoliAnnotation (arrayAttr={2,3,4})
如果数组属性中只有一个元素,这时候属性值部分可以省略大括
枚举类型的属性
EnumTest.TrafficLamp lamp() ; 
@LiaoliAnnotation (lamp=EnumTest.TrafficLamp.GREEN) 
注解类型的属性:
MetaAnnotation annotationAttr() default @MetaAnnotation("xxxx"); 
@MyAnnotation(annotationAttr=@MetaAnnotation(“yyy”) ) 
可以认为上面这个@MyAnnotation是MyAnnotaion类的一个实例对象,同样的道理,可以认为上面这个@MetaAnnotation是MetaAnnotation类的一个实例对象,调用代码如下:
        MetaAnnotation ma =  myAnnotation.annotationAttr();
        System.out.println(ma.value());
 
	
				
		
原创粉丝点击