1.注解是什么?
注解,元数据的一种形式,提供与程序有关的数据,但又不是程序的一部分。注解对它们注解的代码操作没有直接影响。
附注:元数据是指用来描述数据的数据,更通俗一点,就是描述代码间关系,或者代码与其他资源(例如数据库表)之间内在联系的数据。在Java中,使用Annotation的概念来描述元数据。元数据以标签的形式存在于java代码中,元数据标签的存在并不影响程序代码的编译和执行。
2.注解有什么用?
- 给编译器提供信息——注解可以被编译器用来检测错误和抑制警告。
- 编译时和部署时处理——软件工具处理注解信息生成代码、XML文件等等
- 运行时处理——一些注解适用于在运行时检查。
3.注解被用于哪些地方?
注解可以应用于声明:类,字段,方法,以及其他程序元素的声明。
声明的类上:
@Entity public class Person{...}
字段上:
public class Person{ @NotNull private String name; }
方法上:
@Override public String toString(){...}
Java SE 8 发行版,注解也可以应用于使用的类型。下面是一些例子:
创建类实例的表达式中:
new @Inner InnerObject();
类型转换中:
String value = (@NotNull String) jsonObject;
implements语句中:
class UnmodifiableList<T> implements @Readonly List<@Readonly T> { ... }
声明抛出的异常中:
void doWork() throws @BaseServiceException ChannelException { ... }
像这种形式的注解,称为“类型注解”。
4.我们如何使用它?
4.1.声明注解
语法:
[public/abstract] @interface Xxx{ [public/abstract] [dataType] xx(); [public/abstract] [dataType] xx() default x; }
示例:
package org.springmorning.demo.javabase.annotation; /** * @author 春晨 * @date 2019/1/8 9:30 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10234764.html */ public @interface Name { //名字 String first(); //姓氏 String last(); }
一、这种没有注解类型元素的注解,我们称之为标记注解类型(a marker annotation type),如下例的@Identifier注解;
package org.springmorning.demo.javabase.annotation; /** * @author 春晨 * @date 2019/1/8 8:58 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10234764.html */ public @interface Identifier { }
二、这种只有一个注解类型元素的注解,我们称之为单元素注解类型(a single-element annotation type),如下例的@Age注解;
三、定义注解类型元素时,可以设置默认值,如上例中的@Age注解;
package org.springmorning.demo.javabase.annotation; /** * @author 春晨 * @date 2019/1/7 19:56 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10234764.html */ public @interface Age { /** * 声明有默认值的注解属性 */ String value() default "N/A"; }
注意:单元素注解,根据惯例,元素名称为value,如果注解类型元素名称为value,在使用它的时候可以省略名字;否则的话,名字不能省略。如下面示例,Magazine类中对age字段使用@Age注解,就省略了value名称。
四、注解声明的语法,允许除方法声明之外的其他元素声明,如下示例,声明注解要使用的枚举:
package org.springmorning.demo.javabase.annotation; /** * @author 春晨 * @date 2019/1/8 9:06 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10234764.html */ public @interface Sex { enum SEX { MALE, FEMALE } SEX value(); }
五、在使用注解时,声明的类、方法、变量等其他程序元素上面可以有多个注解,如下面示例中对Magazine类中的age字段就使用了@Age注解和@SuppressWarning注解:
六、声明注解的元素,只能是以下类型:
- 所有基本类型(boolean,char,byte,short,int,long,float,double)
- String
- Class
- enum
- Annotation
- 以上类型的数组类型
如下面示例中,Description注解里面元素的类型就包括String、long、enum对象Version、String数组和Class这几种;
七、要想使@Description出现在Javadoc-generated文档中,你必须用@Documented注解给@Description注解定义。
package org.springmorning.demo.javabase.annotation; /** * @author 春晨 * @date 2019/1/7 14:01 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10234764.html */ public @interface Author { Name name(); }
以下声明一个要示例中要使用的枚举:
package org.springmorning.demo.javabase.annotation; /** * @author 春晨 * @date 2019/1/7 17:19 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10234764.html */ public enum Version { V_1_0("1.0"), V_2_0("2.0"); public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } private String version ; private Version(String version) { this.version = version; } }
package org.springmorning.demo.javabase.annotation; import java.lang.annotation.Documented; /** * @author 春晨 * @date 2019/1/7 17:08 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10234764.html */ interface Formatter {} class CommonFormat implements Formatter {} class SpecificFormat implements Formatter{} @Documented public @interface Description { //作者 Author author(); //日期 long date(); //版本 Version version() default Version.V_1_0; //上次修改时间 String lastModified() default "N/A"; //由谁修改 String lastModifiedBy() default ""; //贡献者 String[] contributors(); //优先使用的打印格式 Class<? extends Formatter> prettyPrinter(); }
package org.springmorning.demo.javabase.annotation; /** * @author 春晨 * @date 2019/1/7 13:59 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10234764.html */ @Description( author = @Author(name=@Name(first = "晨", last = "春")), date = 20190102, version = Version.V_2_0, lastModified = "2019-01-07 08:11:22", lastModifiedBy = "张三", contributors = {"张三","李四"}, prettyPrinter = CommonFormat.class ) public class Magazine { @Identifier private String id; @Author(name=@Name(first = "四", last = "李")) private String author; @Age("12") @SuppressWarnings("unchecked") private int age; @Sex(Sex.SEX.MALE) private String sex; @Override public String toString(){ return super.toString(); } }
4.2 预定义注解
Java SE API预定义了一系列的注解类型,这些注解根据其中一些注解类型用于Java编译器,另一些用于其他注解,如以上示例中@Document、@Override和@SuppressWarnings注解。
Java SE 8,预定义的注解有:@Target、@Retention、@Documented、@Inherited、@Repeatable、@Override、@SuppressWarnings、@Deprecated、@SafeVarargs和@FunctionalInterface这十种。
其中,我们把@Target、@Retention、@Documented、@Inherited、@Repeatable这五种注解,称为“元注解”,Java中的元注解专职负责注解其他注解的,用来标示其他注解的适用范围和作用域。
5. 下节继续
下节将给大家讲解,元注解@Target的使用。