注解定义完后后,就可以使用注解了。注解的使用非常简单,注解可以添加在类、成员方法、成员变量、参数声明前面,每个类、成员方法、成员变量前面可以添加多个注解。注解添加语法如下:
@注解名称(属性名称1=值1,属性名称2=值2,……)
当注解有多个属性需要赋值时,每个属性赋值语句之间用英文逗号分隔。
例如:
@Rate(rate=0.035) double dRate;
注解Rate的属性rate被赋值为0.035,该注解添加在变量dRate的前面,因此该注解作用于dRate变量。
如果注解的属性类型是数组,赋值方式为:
@Demo(value={20,30},name=”lihua”)
public void showDemo() {};其中,Demo为注解名称,该注解有两个属性,分别是value属性和name属性,value属性是int类型的数组,name属性是String类型。
Demo注解添加在showDemo()方法的前面,因此该注解作用于showDemo()方法。
在程序运行过程中,如果要读取注解和注解内部定义的属性,只能使用反射技术,如果没有反射技术,注解的作用就大打折扣了。
与反射技术相关的Class类、Constructor类、Method类、Field类都定义了一些方法用于操作注解。
Class类定义的常用注解方法说明如下:
● Annotation[] getAnnotations()
该方法用于返回Annotation类型的数组,数组包含类内部的所有注解。
● <A extends Annotation> A getAnnotation(Class<A> annotationClass)
该方法用于返回类中指定类型的注解,类型由annotationClass指定,如果没有该类型的注解,返回空。
类Constructor、Field和Method均继承了AccessibleObject类,该类定义了用于注解操作的方法,该类常用的注解操作方法说明如下:
● Annotation[] getAnnotations()
该方法用于返回Annotation类型的数组,数组包含当前元素上的所有注解。
● <T extends Annotation> T getAnnotation(Class<T> annotationClass)
该方法用于返回当前元素上指定类型的注解,类型由annotationClass指定,如果没有该类型的注解,返回空。
● <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass)
该方法用于返回扩展Annotation类型的数组,该数组包含当前元素上指定annotationClass类型的注解。如果当前元素上没有该类型的注解,返回长度为0的空数组。
● Annotation[] getDeclaredAnnotations()
该方法返回Annotation类型的数组,数组包含当前元素上直接出现的所有注解,此方法忽略继承的注解。如果当前元素上没有注解,则返回值为长度为0的数组。
● <T extends Annotation> T[] getDeclaredAnnotationsByType (Class<T> annotationClass)
该方法用于返回扩展Annotation类型的数组,该数组包含当前元素直接出现的类型为annotationClass的注解。如果当前元素上没有该类型的注解,返回长度为0的空数组。
● <T extends Annotation> T getDeclaredAnnotation (Class<T> annotationClass)
该方法用于返回当前元素上直接出现的指定类型的注解,类型由annotationClass指定,如果没有该类型的注解,返回空。
● boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
该方法用于判断当前元素上是否有指定annotationClass类型的注解,如果有返回true,否则返回false。
案例1:建立Calculation类,该类用于银行定期存款利息计算。定义一个成员变量rate,在rate变量前面添加注解Rate,rate的值来自于Rate注解提供的元数据rate。定义一个方法interest(),用于计算本金利息。建立CalculationTest测试类,验证Rate注解的读取。
在annotation包下新建Calculation类。代码如下:
package annotation;
/**
* @ClassName: Calculation
* @Description: 注解与反射(使用注解)案例1
* @author 编程训练营
* @date
*
*/
public class Calculation {
// 添加Rate注解
@Rate(rate=0.035)
double dRate;
public Calculation()
{
dRate = 0.0;
}
/**
* @Title: interest
* @Description: 计算定期存款利息
* @param @param capital
* @param @param year
* @param @return 参数
* @return double 返回类型
* @throws
*/
public double interest(double capital,int year)
{
return capital*dRate*year;
}
/**
* @return the dRate
*/
public double getdRate() {
return dRate;
}
/**
* @param dRate the dRate to set
*/
public void setdRate(double dRate) {
this.dRate = dRate;
}
}注解的使用和类的使用一样,如果注解类和使用注解的类不在同一个包内,需要使用import语句将注解类导入。Rate注解添加到Calculation类dRate成员变量上,也可以同时添加到其它变量上。
在annotation包下新建CalculationTest类。代码如下:
package annotation;
import java.lang.reflect.Field;
/**
* @ClassName: CalculationTest
* @Description: 注解与反射(使用注解)案例1
* @author 编程训练营
* @date
*
*/
public class CalculationTest {
/**
* @Title: main
* @Description: Java程序入口main方法
* @param @param args 参数
* @return void 返回类型
* @throws
*/
public static void main(String[] args) {
// 实例化Calculation类
Calculation calcula = new Calculation();
// 获取Calculation类的Class对象
Class calculaClass = calcula.getClass();
try {
//通过class.getDeclaredField(name)获取指定名称的成员变量
Field field = calculaClass.getDeclaredField("dRate");
//获取该成员变量上的Rate注解
Rate rate = field.getAnnotation(Rate.class);
// 判断注解是否获取成功
if( null != rate )
{
// 注解对象直接访问rate属性
calcula.setdRate(rate.rate());
System.out.printf("定期存款年利息为:%.2f/%%\n",rate.rate()*100);
System.out.println("15000元存款2年定期存款利息为:" + calcula.interest(15000,2));
}
else
{
System.out.println("获取Rate注解失败");
}
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}CalculationTest程序首先通过Calculation实例获取Class对象,通过Class对象的getDeclaredField()方法获取Calculation类成员变量dRate的Field对象,在通过Field类的getAnnotation()方法获取Rate注解,返回的注解对象引用赋值给Rate类型的局部变量rate。
在使用rate对象前,需要判断rate对象是否为空。若不为空,进入利息计算语句块,注解访问属性和类访问属性有一定的差别,注解通过对象名.属性()来访问注解的属性,在属性名称的后面要紧跟一对“()”.
程序执行结果如下图所示:
从执行结果来看,Rate注解获取失败。这是什么原因呢?这是因为在定义Rate注解时,没有给Rate注解添加注解作用范围,因此在程序运行过程就取不到Rate注解了。给注解添加作用范围,就需要涉及到元注解的概念,在下一节课,我们将学习元注解,给注解添加作用范围。