本文共 4128 字,大约阅读时间需要 13 分钟。
从JDK 5.0开始,Java引入了对元数据的支持,即注解(Annotation)。注解是一种特殊的标记,可以在编译、类加载和运行时被读取并执行相应的处理。通过注解,开发者可以在不改变原有逻辑的情况下,在源文件中嵌入补充信息。代码分析工具、开发工具和部署工具可以利用这些信息进行验证或部署。
注解可以像修饰符一样使用,用于修饰包、类、构造器、方法、成员变量、参数、局部变量等。这些信息被保存在注解的“name=value”对中。
框架 = 注解 + 反射机制 + 设计模式
@author 标明开发该类模块的作者,多个作者之间用逗号分隔。@version 标明该类模块的版本@see 参考转向,也就是相关主题@since 从哪个版本开始增加的@param 对方法中某参数的说明,如果没有参数就不能写@return 对方法返回值的说明,如果方法的返回值类型是void就不能写@exception 对方法可能抛出的异常进行说明,如果方法没有用throws显式抛出的异常就不能写
@Override:限定重写父类方法,该注解只能用于方法@Deprecated:用于表示所修饰的元素(类、方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择@SuppressWarnings:抑制编译器警告
Servlet3.0引入了注解,使得不需要在web.xml文件中进行Servlet的部署。
Spring框架中关于“事务”的管理
使用@interface关键字定义新的注解类型。自定义注解自动继承了java.lang.annotation.Annotation接口。
注解成员变量通过无参数方法的形式声明,返回类型定义了成员的名字和类型。类型只能是八种基本数据类型、String类型、Class类型、enum类型、注解类型以上所有类型的数组。
在定义注解成员变量时为其指定初始值,可以使用default关键字指定初始值。
没有成员定义的注解称为标记注解;包含成员变量的注解称为元数据注解。
如果注解有成员,使用注解时需要指明成员的值。
元注解是对现有注解进行解释说明的注解。
用于指定注解的生命周期,包含一个RetentionPolicy类型的成员变量,必须为value成员变量指定值:
用于指定被修饰的注解能用于修饰哪些程序元素。@Target也包含一个名为value的成员变量。
用于指定被该元注解修饰的注解类将被Javadoc工具提取成文档。默认情况下,Javadoc不包括注解。定义为Documented的注解必须设置Retention值为RUNTIME。
被它修饰的注解将具有继承性。如果某个类使用了被@Inherited修饰的注解,其子类将自动具有该注解。
在java.lang.reflect包下新增了AnnotatedElement接口,该接口代表程序中可以接受注解的程序元素。当一个Annotation类型被定义为运行时Annotation后,该注解才是运行时可见的,当class文件被载入时保存在class文件中的Annotation才会被虚拟机读取。
程序可以调用AnnotatedElement对象的如下方法来访问Annotation信息:
示例:
@Testpublic void testGetAnnotation() { Class clazz = Person.class; Annotation[] annotations = clazz.getAnnotations(); for (int i = 0; i < annotations.length; i++) { System.out.println(annotations[i]); }} 输出结果:
@MyAnnotation(value="hello")
Java8对注解处理提供了两点改进:可重复的注解和可用于类型的注解。此外,反射也得到了加强,在Java8中能够得到方法参数的名称。这会简化标注在方法参数上的注解。
定义一个MyAnnotations注解,里面是MyAnnotation的一个数组:
public @interface MyAnnotations { MyAnnotation[] value();} 通过@MyAnnotations来重复使用@MyAnnotation:
@MyAnnotations({@MyAnnotation(value="hello"), @MyAnnotation(value="world")}) class Person { private String name; private int age; public Person() {} public Person(String name, int age) { this.name = name; this.age = age; } public void walk() { System.out.println("人走路"); } public void eat() { System.out.println("人吃饭"); }} 在JDK8之后可以使用@Repeatable这个注解:
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})@Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotations { MyAnnotation[] value();} 在MyAnnotation上声明@Repeatable,成员值为MyAnnotations.class:
@Repeatable(MyAnnotations.class)@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})@Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotation { String value() default "hello";} 这样@MyAnnotation这个注解就可以重复使用了:
@MyAnnotation(value="hello")@MyAnnotation(value="world") class Person { private String name; private int age; public Person() {} public Person(String name, int age) { this.name = name; this.age = age; } public void walk() { System.out.println("人走路"); } public void eat() { System.out.println("人吃饭"); }} @Repeatable(MyAnnotations.class)@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, TYPE_PARAMETER})public @interface MyAnnotation {String value() default "hello";}
示例:
class Generic{ }
@Repeatable(MyAnnotations.class)@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, TYPE_PARAMETER, TYPE_USE})public @interface MyAnnotation {String value() default "hello";}
示例:
class Generic{ public void show() throws @MyAnnotation RuntimeException { ArrayList arrayList = new ArrayList<>(); int num = (@MyAnnotation int) 10L; }}
转载地址:http://dnpi.baihongyu.com/