注解(Annotation)可以添加到类、方法、变量、参数的声明前面,类似于注释。不过注解和注释是截然不同的两个概念。
注释仅对代码起到解释作用,方便程序员阅读代码。
注解虽然也能对代码起到解释作用,但注解的主要目的不是对代码进行注释。注解可以为代码提供元数据,利用这些元数据,注解可以起到如下作用:
(1)为编译器提供额外的代码信息;
(2)编译器可以利用注解在编译过程中对代码进行检查;
(3)在程序运行过程中,可以利用反射技术解析注解并提取元数据,进行相应的操作和处理;
(4)javadoc可以利用注解提供的元数据生成与源代码配套的帮助文档。
元数据是描述数据的数据,在这里可以理解为描述代码的数据,为代码提供额外的数据。例如,在前面课程的案例代码中,当子类方法重写父类方法时,会要求子类在重写父类方法的声明前面添加“@Override”,“@Override”就是一个已定义并用于编译检查的注解,这是一个标记注解,注解的元数据就是自身。在编译过程中,当编译器检测到某个方法添加了“@Override”注解,编译器就会检查当前方法在父类是否存在,如果父类没有该方法,编译器就会给出警告信息。
Java主流开发框架Spring内部就定义了大量注解,程序员可以在编写的Java代码中使用这些注解。当Spring加载类时会扫描这些注解,并根据注解内容进行程序的装配。
注解主要分为四大类:一类是来自Java内部定义的注解,也称为内置的注解,如@Override、@Deprecated等注解;一类是第三方框架定义的注解,如Spring框架的@Autowired、@Service等注解;一类是程序内部定义的注解,编写程序时自己来定义注解;一类是元注解,元注解在Java中也被定义,元注解主要用于对自定义的注解进行描述,也可以理解为注解的注解。
如何在程序内部定义注解呢?
在Java语言中,注解也是一个类,注解和类的定义基本相同,注解也有属性,但没有方法。注解的定义语法如下:
public @interface 注解名称
{
类型 属性名称() default 默认值;
……
}@interface是定义注解的修饰符,注解名称是自定义注解的名字,命名方式和类的命名方式相同。注解的主体内容由一对“{}”括起来,主体内容主要存放注解的属性,注解可以有多个注解属性,也可以没有注解属性,没有注解属性时,“{}”括号内不需要写任何内容。
注解属性的定义类似类方法的定义,属性名称前面是属性的类型,类型可以是基本数据类型、String、Class、枚举,也可以是前面类型的数组。类型后面是属性名称,类型和属性名称之间需要用空格隔开,紧跟属性名称是一对“()”括号,括号内不需要写任何内容。如果需要对属性设置默认值,可以在属性名称后面使用default关键字来设置属性的默认值。
案例1:建立Rate注解,Rate注解为其它类提供银行定期存款利率元数据。
新建项目PCoreUnit9,在PCoreUnit9项目新建annotation包,在annotation包下新建Rate注解。建立注解步骤如下:
(1)用鼠标选择src目录下的annotation包,单击鼠标右键,在弹出的菜单项列表中选择【New】菜单项;
(2)在弹出的【New】子菜单项列表,选择【Annotation】菜单项;
(3)在弹出的对话框中(如下图所示)Name输入域输入注解名称“Rate”,单击【Finish】按钮即可。
Rate注解代码如下:
package annotation;
/**
* @ClassName: Rate
* @Description: 注解与反射(认识注解)案例1
* @author 编程训练营
* @date 2020年1月4日
*
*/
public @interface Rate {
// 利率默认值0.03
double rate() default 0.03;
}Rate是注解的名称,Rate注解内部定义了一个double类型的属性rate,该属性的默认值为0.03。Rate注解可以为其它类提供银行定期存款利率元数据。
既然Rate注解为其它类提供银行定期存款利率数据,那么注解是如何使用的呢?其它类是如何读取注解并获取注解属性呢?这就要用到Java的反射技术,在下一节课我们将会学习如何利用反射技术来读取注解。