JavaSE5引入了很多语言变化,注解(元数据)就是其中之一,主要是给代码增加补充信息。注解不影响代码的逻辑,只是在编译运行时为代码增加配置和描述功能。注解使用@interface来定义注解。如下:@interfaceMapping{Stringname();字符串[]路径()默认{};Typetype()defaultType.GET;}注解不能包含extends子句。但是,所有注释类型都隐式地和直接地扩展了java.lang.annotation.Annotation接口。当Mapping注解中只需要一个注解元素时,可以将name设置为value,这样在指定value的时候就不需要指定注解元素的名字了。比如@Mapping("get")。注解中的元素类型可以使用基本类型、String、Class、枚举、注解类型以及由上述类型组成的数组。并且可以使用default为注解元素提供默认值。String[]path()default{}如上图是一个注解元素,设置了默认值。注解声明定义的注解需要在代码中使用。声明注释可以出现在包、类、接口、方法、构造函数、实例字段、局部变量、参数变量和参数类型上。下面给出一个例子:@Mapping("example")publicclassSample{...}注意:局部变量的注释只能在源代码级别处理。类文件不描述局部变量。因此,当一个类被编译时,所有的局部变量注解都会被丢弃。同样,包上的注释不能存在于源代码级别之外。内置注解JavaSE提供了很多注解,但大多数都是专门的注解。其中包括规则注释和元注释。@Deprecated这个注解用来标记不想被使用的项目。使用@Deprecated标记时,编译器会发出警告。此注释与Javadoc标记@deprecated具有相同的效果。@SuppressWarnings这个注解告诉编译器抑制某些类型的警告消息。比如@SuppressWarnings("unchecked")。@Override该注解只能应用于方法,表示当前方法定义将覆盖基类的方法。如果你在你的类中覆盖了equals(Objectobj)方法,你可以使用@Override注解标记。不要对没有被覆盖的方法使用@Override,因为编译器会报错。@SafeVarargs此注解用于安全使用带有通用可变参数的参数。作用于方法或构造函数。此注解是为JavaSE7添加的。@FunctionalInterface此注解用于标记只有一个抽象方法的接口,声明为功能接口。这个注解是JavaSE8新增的。其中,一种不包含注解元素的特殊类型的注解称为标记注解,其唯一目的是标记声明。确定标记注释是否存在的最佳方法是使用isAnnotationPresent()方法,该方法由AnnotatedElement接口定义。Meta-annotations还有一些用于描述注解接口行为属性的注解,称为元注解(metaannotations)。Java提供了一些元注释。如下图:@Retention@Retention定义了注解的保留策略,决定注解在什么地方被丢弃。相反,保留策略封装在java.lang.annotation.RetentionPolicy枚举中。如下:RetentionPolicy.SOURCE只在源文件中保留,编译时丢弃。RetentionPolicy.CLASS在编译期间存储到.class文件中。但是这些注释在运行时无法通过JVM获得。RetentionPolicy.RUNTIME在编译期间存储到.class文件中,这些注释在运行时通过JVM可用。因此,可以通过反射机制读取注解信息。注意:局部变量声明的注释不能存储在.class文件中。如果@Retention不存在,则Annotation默认为CLASS。因为通常我们自定义的Annotation都是RUNTIME,所以一定要加上元注解@Retention(RetentionPolicy.RUNTIME):@Retention(RetentionPolicy.RUNTIME)public@interfaceMapping{Stringname();字符串[]路径()默认{};Typetype()defaultType.GET;}映射注解可以在程序执行过程中通过JVM获取。@Target@Target定义了注解的声明类型,用于确定注解应用的位置,如类、方法、变量、参数、包等。相反,定义的类型封装在java.lang.annotation.ElementType枚举中。如下:ElementType.ANNOTATION_TYPE注解类型声明。ElementType.CONSTRUCTOR构造函数声明。ElementTyoe.FIELD字段变量声明。ElementType.LOCAL_VARIABLE局部变量声明。ElementType.METHOD方法声明。ElementType.PACKAGE包声明。ElementType.PARAMETER参数声明。ElementType.TYPE类、接口或枚举声明。ElementType.TYPE_PARAMETER类型参数。ElementType.TYPE_USE类型用法。定义的注解@Mapping可以用在方法上,如下所示:@Target(ElementType.METHOD)public@interfaceMapping{Stringname();字符串[]路径()默认{};Typetype()defaultType.GET;}也可以在@Target注解中指定多个值,用{}括起来。像这样:@Target({ElementType.METHOD,ElementType.FIELD})public@interfaceMapping{Stringname();字符串[]路径()默认{};Typetype()defaultType.GET;}如果不使用@Target,可以应用于任何语句。所以一般来说,明确指定目标是个好主意,以明确注释的用途。TYPE_PARAMETER和TYPE_USE枚举常量是JavaSE8新加入的枚举常量,类型注解必须包含ElementType_USE,这样可以注解方法的返回类型,方法内部this的类型,强制转换,数组层次,继承类,并抛出条款。泛型也可以被注释,包括泛型类型参数边界和泛型类型参数。@Documented@Documented注解是一个标记接口,用于通知工具注解将被记录。@Documented旨在仅注释其他注释。默认情况下javadoc不处理注解,但是在注解上标记@Documented会被javadoc之类的归档工具进行归档处理。@Documented@Target(ElementType.METHOD)public@interfaceMapping{字符串名称();字符串[]路径()默认{};Typetype()defaultType.GET;}@Inherited@Inherited是Another注解语句的标记注解。@Inherited标注的注解可以被子类继承,只能用于@Target(ElementType.TYPE)类型注解的注解。因此,在为特定注解查询子类时,如果子类中不存在该注解,则检查基类。如果该注解存在于超类中并且使用@Inherited进行注解,则将返回该注解。定义一个用@Inherited标记的注解@Persistent。@Inherited@interfacePersistent{}这里使用@Persistent注解来表示一个类的对象可以存储在数据库中。@PersistentpublicclassPerson{},那么继承自Person的子类也会自动注解为persistent。publicclassStudentextendsPerson{}@RepeatableJavaSE8可以使用@Repeatable注解将相同类型的注解多次应用于一个项目。为了保持向后兼容性,可重复注解的实现者需要提供一个容器注解,将这些可重复注解存储在一个数组中。@Repeatable(Mappings.class)@Target(ElementType.METHOD)public@interfaceMapping{字符串名称();Stringpath()默认"";Typetype()defaultType.GET;}@Target(ElementType.Type)public@interfaceMappings{Mapping[]value();}@Repeatable修饰后,只要用户提供两个或多个@Mapping注解,就会自动包装到@Mappings注释中。@Mapping(name="GETMapping",path="/profile")@Mapping(name="POSTMapping",path="/profile",type=Type.POST)publicclassAnnotationTest{}在这里,使用getAnnotation()方法获取重复注解,需要传入容器注解的类,而不是重复注解本身。AnnotatedElement接口还提供了两个方法getAnnotationsByType()和getDeclaredAnnotationsByType(),可以直接操作重复的注解。@Native使用@Native注解修饰成员变量,表示该变量可以被本地代码引用,常被代码生成工具使用。@Native注解不常使用。注解处理当注解指定了RUNTIME保留策略时,运行时可以通过反射API查询注解。反射API中使用的Class、Field、Method、Constructor等类都实现了AnnotatedElement注解接口。该接口提供了几种获取注解的方法。其中getAnnotationsByType()、getDeclaredAnnotation()和getDelaredAnnotationsByType()方法都是JavaSE8中新增的方法。getAnnotation()AnnotatedElement注解接口提供的getAnnotation()方法可以获取对象关联的注解。此方法的一般形式如下:
