Logo

郎哥编程

使用注解

2020-01-05 159

注解定义完后后,就可以使用注解了。注解的使用非常简单,注解可以添加在类、成员方法、成员变量、参数声明前面,每个类、成员方法、成员变量前面可以添加多个注解。注解添加语法如下:

@注解名称(属性名称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对象是否为空。若不为空,进入利息计算语句块,注解访问属性和类访问属性有一定的差别,注解通过对象名.属性()来访问注解的属性,在属性名称的后面要紧跟一对“()”.

程序执行结果如下图所示:

image.png                                             

从执行结果来看,Rate注解获取失败。这是什么原因呢?这是因为在定义Rate注解时,没有给Rate注解添加注解作用范围,因此在程序运行过程就取不到Rate注解了。给注解添加作用范围,就需要涉及到元注解的概念,在下一节课,我们将学习元注解,给注解添加作用范围。

代码在线纠错(通义千问 qwen-max)

支持粘贴多个代码文件,提交后由阿里云通义千问自动分析代码漏洞、语法错误、逻辑问题并给出修改建议。
您已解锁 AI 代码纠错功能,可正常使用!

评论区

登录 后发表评论
暂无评论