什么是注解?
注解是JDK1.5引入的一个语法糖,它主要用来看成元数据,简朴的说就是用于表明数据的数据。在Java中,类、要领、变量、参数、包都可以被注解。许多开源框架都利用了注解,譬喻Spring、MyBatis、Junit。我们泛泛最常见的注解大概就是@Override了,该注解用来标识一个重写的函数。
注解的浸染:
界说一个注解很是简朴,只需要遵循以下的语礼貌则:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @Documented public @interface ValidateInt { // 它们看起来像是界说一个函数,但其实这是注解中的属性 int maxLength(); int minLength(); }
我们发明上面的代码在界说注解时也利用了注解,这些注解被称为元注解。浸染于注解上的注解称为元注解(元注解其实就是注解的元数据),Java中一共有以下元注解。
@Target:用于描写注解的利用范畴(注解可以用在什么处所)。
@Retention:注解的生命周期,用于暗示该注解会在什么时期保存。
@Documented:暗示该注解会被作为被标注的措施成员的民众API,软件开发,软件开发,因此可以被譬喻javadoc此类的东西文档化。
@Inherited:暗示该注解是可被担任的(假如一个利用了@Inherited修饰的annotation范例被用于一个class,则这个annotation将被用于该class的子类)。
相识了这些基本常识之后,接着完成上述界说的@ValidateInt,我们界说一个Cat类然后在它的成员变量中利用@ValidateInt,并通过反射举办数据校验。
public class Cat { private String name; @ValidateInt(minLength = 0, maxLength = 10) private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public static void main(String[] args) throws IllegalAccessException { Cat cat = new Cat(); cat.setName("楼楼"); cat.setAge(11); Class<? extends Cat> clazz = cat.getClass(); Field[] fields = clazz.getDeclaredFields(); if (fields != null) { for (Field field : fields) { ValidateInt annotation = field.getDeclaredAnnotation(ValidateInt.class); if (annotation != null) { field.setAccessible(true); int value = field.getInt(cat); if (value < annotation.minLength()) { // .... } else if (value > annotation.maxLength()) { // .... } } } } } }
注解的实现
注解其实只是Java的一颗语法糖(语法糖是一种利便措施员利用的语礼貌则,但它其实并没有外貌上那么神奇的成果,只不外是由编译器帮措施员生成那些繁琐的代码)。在Java中这样的语法糖尚有许多,譬喻enum、泛型、forEach等。
通过阅读JLS(Java Language Specification(当你想相识一个语言特性的实现时,最好的要领就是阅读官方类型)发明,注解是一个担任自java.lang.annotation.Annotation接口的非凡接口,原文如下:
An annotation type declaration specifies a new annotation type, a special kind of interface type. To distinguish an annotation type declaration from a normal interface declaration, the keyword interface is preceded by an at-sign (@). Note that the at-sign (@) and the keyword interface are distinct tokens. It is possible to separate them with whitespace, but this is discouraged as a matter of style. The rules for annotation modifiers on an annotation type declaration are specified in §9.7.4 and §9.7.5. The Identifier in an annotation type declaration specifies the name of the annotation type. It is a compile-time error if an annotation type has the same simple name as any of its enclosing classes or interfaces. The direct superinterface of every annotation type is java.lang.annotation.Annotation.
package java.lang.annotation; /** * The common interface extended by all annotation types. Note that an * interface that manually extends this one does <i>not</i> define * an annotation type. Also note that this interface does not itself * define an annotation type. * * More information about annotation types can be found in section 9.6 of * <cite>The Java™ Language Specification</cite>. * * The {@link java.lang.reflect.AnnotatedElement} interface discusses * compatibility concerns when evolving an annotation type from being * non-repeatable to being repeatable. * * @author Josh Bloch * @since 1.5 */ public interface Annotation { ... }