Annotation注解-高级

来源:互联网 发布:小米官网和淘宝旗舰店 编辑:程序博客网 时间:2024/06/06 07:41

一、Annotation高级特性

@Retention

   java.lang.annotation.Retention型态可以在您定义Annotation型态时,指示编译程序该如何对待您的自定义的Annotation型态

   预设上编译程序会将Annotation信息留在.class档案中,但不被虚拟机读取,而仅用于编译程序或工具程序运行时提供信息

在使用Retention型态时,需要提供java.lang.annotation.RetentionPolicy枚举型态

package java.lang.annotation;

public enumRetentionPolicy

 {

    SOURCE, //编译程序处理完Annotation信息后就完成任务

    CLASS, //编译程序将Annotation储存于class当中,缺省

    RUNTIME //编译程序将Annotation储存于class当中,可由VM读入

}

RetentionPolicySOURCE的例子是@SuppressWarnings

  仅在编译时期告知编译程序来抑制警告,所以不必将这个信息储存于.class档案

  RetentionPolicyRUNTIME的时,可以用Java设计一个程序代码,让JVM读出Annotation信息,以便在分析程序时使用,搭配反射(Reflection)机制,就可以达到这个目的。

java.lang.annotation.AnnotatedElement接口

public Annotation getAnnotation(ClassannotationType);

public Annotation[] getAnnotations();

public Annotation[] getDeclaredAnnotations();

public booleanisAnnotationPresent(ClassannotationType);

ClassConstructorFieldMethodPackage等类别,都实现了AnnotatedElement接口

参见程序实例

package com.cienet.advanced;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)public @interface RetentionAnnotation { String hello() default "cienet";String world();}
package com.cienet.advanced;public class RetentionClass {@RetentionAnnotation(world = "shanghai")//@Deprecated//@SuppressWarnings("unchecked")public void output() {System.out.println("output something");}}
package com.cienet.advanced;import java.lang.annotation.Annotation;import java.lang.reflect.Method;public class RetentionAnnotationTest {public static void main(String[] args) throws Exception {Class<RetentionClass> myTest = RetentionClass.class;Method method = myTest.getMethod("output", new Class[]{});if (method.isAnnotationPresent(RetentionAnnotation.class)) {RetentionAnnotation annotationTest = method.getAnnotation(RetentionAnnotation.class);String hello = annotationTest.hello();String world = annotationTest.world();System.out.println(hello);System.out.println(world);}//Annotation[] annotations = method.getAnnotations();//for (Annotation annotation : annotations) {//System.out.println(annotation.annotationType().getName());//}}}

@Target

  表示该注解用于什么地方,可能的参数由java.lang.annotation.ElementType决定。

package java.lang.annotation;

public enumElementType

{

    TYPE, //适用class,interface,enum

    FIELD, //适用field

    METHOD, //适用method

    PARAMETER, //适用method上之parameter

    CONSTRUCTOR, //适用constructor

    LOCAL_VARIABLE, //适用局部变量

    ANNOTATION_TYPE, //适用annotation型态

    PACKAGE //适用package

}

参见范例

package com.cienet.advanced;public class TargetClass {@TargetAnnotation("xyz")public void doSomething() {System.out.println("hello world");}}
package com.cienet.advanced;import java.lang.annotation.Target;import java.lang.annotation.ElementType;//@Target(ElementType.TYPE)public @interface TargetAnnotation {String value();}

@Documented

  这个annotation非常简单,也非常容易理解,使用过javadoc命令的人都会很清楚,我们可以用javadoc命令将方法,类,变量等前面的注释转换成文档,在默认的情况下javadoc命令不会将我们的annotation生成到doc中去的,所以使用该标记就是告诉jdk让它也将annotation生成到doc中去。

  参见程序实例

package com.cienet.advanced;import java.lang.annotation.Documented;//@Documentedpublic @interface DocumentedAnnotation {String hello();}
package com.cienet.advanced;public class DocuemntedAnnotationTest {@DocumentedAnnotation(hello = "welcome")public void method() {System.out.println("test document");}}

@Inherited

  预设上父类别中的Annotation并不会被继承至子类别中可以在定义Annotation型态时加上@Inherited使注解能继承到子类中。

l@Inherited

  JDK的文档提到@Inherited只能放在类上,本人测试发现放在方法上也是可以的。

  注意:该注解放在方法上的时候子类重写父类方法时该注解会被覆盖掉。

   参见程序实例

package com.cienet.advanced;import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface InheritedAnnotation {String value();}
package com.cienet.advanced;import java.lang.reflect.Method;public class InheritedAnnotationTest {public static void main(String[] args) throws Exception{Class<Child> childClass = Child.class;if (childClass.isAnnotationPresent(InheritedAnnotation.class)) {InheritedAnnotation inheritedAnnotation = childClass.getAnnotation(InheritedAnnotation.class);String value = inheritedAnnotation.value();System.out.println(value);}//Method method = childClass.getMethod("doSomething", new Class[]{});//if (method.isAnnotationPresent(InheritedAnnotation.class)) {//InheritedAnnotation inheritedAnnotation = method.getAnnotation(InheritedAnnotation.class);//String value = inheritedAnnotation.value();//System.out.println(value);//}}}
二、APT
apt: annotation processing tool.
apt 是一个可以处理annotation的命令行工具,它提供了处理annotation的框架:它启动后扫描源代码中的annotation,并调用我们定义好的annotation处理器完成我们所要完成的工作。它是在编译时针对原代码级别的解析,并在解析时生成新的源码和其他的文件,并对生成的源码进行编译。
原创粉丝点击