黑马程序员 java_注解

                                ------- android培训java培训、期待与您交流! ----------

 

 

注解

 

注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标 记,看你有什么标记,就去干相应的事。标记可以加在包,类,字段,方法,方法的参数以及局部变量上。

annotation为所以注解类的顶层接口。

 

 

注解的应用结构图


黑马程序员 java_注解_第1张图片
 

首先需要定义一个注解A,然后这个注解的需要应用于某个类B。最后一个类C在创建类B的对象时,就会发现B上有注解,C类就知道什么该做什么不该做。例如B上标注了某些方法已经过时,则C中不能使用此方法。
注解就相当于一个你的源程序中要调用的一个类,要在源程序中应用某个注解,得先准备好这个注解类。就像你要调用某个类,得先有开发好这个类。

 

 

格式
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItcastAnnotation {注释的主体,包括注释属性} 
下面依次介绍。

 

@Retention

指示注释类型的注释要保留多久。就是注解的生命周期,有三种取值,由枚举 RetentionPolicy的三个元素表示。

 

CLASS

编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。

RUNTIME

编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。

SOURCE

编译器要丢弃的注释。

注意:

如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS。

 

@Target元注解

指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在 Target 元注释,则声明的类型可以用在任一程序元素上。如果存在这样的元注释,则编译器强制实施指定的使用限制。简单说就是表示注释可以应用于哪些"对象"。这个"对象"用程序元素这个概念表示。这些程序元素也被封装到枚举中了,此枚举为ElementType,包含元素:

ANNOTATION_TYPE

注释类型声明

CONSTRUCTOR

构造方法声明

FIELD

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

LOCAL_VARIABLE

局部变量声明

METHOD

方法声明

PACKAGE

包声明

PARAMETER
参数声明
TYPE
类、接口(包括注释类型)或枚举声明

 

 

 

 

 

 

为注解增加基本属性

 

什么是注解的属性

一个注解相当于一个胸牌,如果你胸前贴了胸牌,就是传智播客的学生,否则,就不是。如果还想区分出是传智播客哪个班的学生,这时候可以为胸牌在增加一个属性来进行区分。

 

格式为:

属性类型 属性名();

例如在注解中添加一个属性:String value();

某个类在应用这个注解时,就需要给color赋值:@ItcastAnnotation(value="xx")

 

 

 

为属性指定缺省值:

value属性:

String value() default "zxx";

如果注解中有一个名称为value的属性,且你只想设置value属性(即其他属性都采用默认值或者只有一个value属性),那么可以省略value=部分,例如:@ItcastAnnotation("lhm")。

 

 

为注解增加高级属性

 

数组类型的属性

int [] arrayAttr() default {1,2,3};

@ItcastAnnotation(arrayAttr={2,3,4})

如果数组属性中只有一个元素,这时候属性值部分可以省略大括

 

枚举类型的属性

假设EnumTest.TrafficLamp为一个枚举,

EnumTest.TrafficLamp lamp() ;

@ItcastAnnotation(lamp=EnumTest.TrafficLamp.GREEN)

 

注解类型的属性:

MetaAnnotation 本身为一个注解,此时被当做一个属性加入到另一个注解上

MetaAnnotation annotationAttr() default @MetaAnnotation("xxxx");

@ItcastAnnotation(annotationAttr=@MetaAnnotation(“yyy”) );

可以认为上面这个@MyAnnotaion是MyAnnotaion类的一个实例对象,同样的道理,可以认为上面这个@MetaAnnotation是MetaAnnotation类的一个实例对象,调用代码如下:

             MetaAnnotation ma =  itcastAnnotation.annotationAttr();

             System.out.println(ma.value());

 

 

实例

 

注解MetaAnnotation

package cn.itcast.day2;

public @interface MetaAnnotation {
	String value();
}

 

 

注解ItcastAnnotation,此注解加上了各种注释和属性

 

package cn.itcast.day2;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import cn.itcast.day1.EnumTest;
//表示生命周期为程序运行阶段
@Retention(RetentionPolicy.RUNTIME)
//注解可在方法和TYPE上
@Target({ElementType.METHOD,ElementType.TYPE})
	public @interface ItcastAnnotation{
	//添加各种属性
	String color() default "blue";
	String value() default "dfdf";
	int[] arrayAttr() default {3,5,7};
	EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.RED;
	//属性为另一个注释MetaAnnotation
	MetaAnnotation annotationAttr() default @MetaAnnotation("1hm");
	
}

 

 

应用注解

package cn.itcast.day2;

import java.lang.reflect.Method;

import javax.jws.soap.InitParam;
//应用注释ItcastAnnotation,并给其中的属性赋值。
@ItcastAnnotation(annotationAttr=@MetaAnnotation("flx"),color="red",value="abc",arrayAttr=1)
public class AnnotationTest {

	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		
		if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)){
			//通过放射获取注释的一个对象
			ItcastAnnotation annotation = (ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
			//打印注解上的各个属性值
			System.out.println(annotation.color());
			System.out.println(annotation.value());
			System.out.println(annotation.arrayAttr().length);
			System.out.println(annotation.lamp().nextLamp().name());
			System.out.println(annotation.annotationAttr().value());
		}
		
		
	}

}

 

          

 

                                                ------- android培训java培训、期待与您交流! ----------

 

你可能感兴趣的:(java)