Annotation注解-高级

一、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(Class annotationType);

public Annotation[] getAnnotations();

public Annotation[] getDeclaredAnnotations();

public booleanisAnnotationPresent(Class annotationType);

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;

//@Documented
public @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)
@Inherited
public @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 处理器完成我们所要完成的工作。它是在编译时针对原代码级别的解析,并在解析时生成新的源码和其他的文件,并对生成的源码进行编译。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值