至于关于编译时的注解,待下篇博客的时候会结合例子讲解一下,目前我也正在学习当中java
提到注解,大多数人应该都不默认,在咱们程序中见到的@Override,@Deprected,@SupressWarnings等等,这些都是注解,只不过是系统本身封装好的,而咱们平时比较少去深刻理解是怎样实现的?程序员
Annotation(注解)就是Java提供了一种元程序中的元素关联任何信息和着任何元数据(metadata)的途径和方法。Annotion(注解)是一个接口,程序能够经过反射来获取指定程序元素的Annotion对象,而后经过Annotion对象来获取注解里面的元数据。面试
根据注解参数的个数,咱们能够将注解分为三类:segmentfault
根据注解使用方法和用途,咱们能够将Annotation分为三类:数组
元注解的做用就是负责注解其余注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它annotation类型做说明。Java5.0定义的元注解:微信
SOURCE(源码时),CLASS(编译时),RUNTIME(运行时),默认为 CLASS,SOURCE 大都为 Mark Annotation,这类 Annotation 大都用来校验,好比 Override, SuppressWarnings
@Target 能够用来修饰哪些程序元素,如 TYPE, METHOD, CONSTRUCTOR, FIELD, PARAMETER 等,未标注则表示可修饰全部ide
ANONOTATION_TYPE(注解类型声明),
PACKAGE(包)
TYPE (类,包括enum及接口,注解类型)
METHOD (方法)
CONSTRUCTOR (构造方法)
FIFLD (成员变量)
PARAMATER (参数)
LOCAL_VARIABLE (局部 变量)
元数据从metadata一词译来,就是“关于数据的数据”的意思。
元数据的功能做用有不少,好比:你可能用过Javadoc的注释自动生成文档。这就是元数据功能的一种。总的来讲,元数据能够用来建立文档,跟踪代码的依赖性,执行编译时格式检查,代替已有的配置文件。若是要对于元数据的做用进行分类,目前尚未明确的定义,不过咱们能够根据它所起的做用,大体可分为三类:函数
其余知识点暂时不介绍,我的以为一会儿介绍太多概念很难消化。下面让咱们一块儿结合例子来使用它。学习
自定义注解大概可分为如下三个步骤:测试
这些类型和它们所支持的类在java.lang.annotation包中能够找到。
/* * 定义注解 MethodInfo * 为方便测试:注解目标为类 方法,属性及构造方法 * 注解中含有三个元素 id ,name和 gid; * id 元素 有默认值 0 */ @Documented @Target({ElementType.TYPE,ElementType.METHOD, ElementType.FIELD,ElementType.CONSTRUCTOR}) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface MethodInfo { String name() default "xujunTest"; int id() default 0; Class<Long> gid(); }
a. 全部方法没有方法体,没有参数没有修饰符,实际只容许 public & abstract 修饰符,默认为 public,不容许抛异常
b. 方法返回值只能是基本类型,String, Class, annotation, enumeration 或者是他们的一维数组
c. 若只有一个默认属性,可直接用 value() 函数。一个属性都没有表示该 Annotation 为 Mark Annotation
String name() default "xujunTest";
/** * 这个类专门用来测试注解使用 * @author xujun */ //类成员注解 @MethodInfo (name="type",gid=Long.class) public class UserAnnotation { //类成员注解 @TestA(name="param",id=1,gid=Long.class) private Integer age; //构造方法注解 @TestA (name="construct",id=2,gid=Long.class) public UserAnnotation(){ } //类方法注解 @TestA(name="public method",id=3,gid=Long.class) public void a(){ Map<String,String> m = new HashMap<String,String>(0); } //类方法注解 @TestA(name="protected method",id=4,gid=Long.class) protected void b(){ Map<String,String> m = new HashMap<String,String>(0); } //类方法注解 @TestA(name="private method",id=5,gid=Long.class) private void c(){ Map<String,String> m = new HashMap<String,String>(0); } public void b(Integer a){ } }
(1) 运行时 Annotation 指 @Retention 为 RUNTIME 的 Annotation,可手动调用下面经常使用 API 解析
method.getAnnotation(AnnotationName.class); method.getAnnotations(); method.isAnnotationPresent(AnnotationName.class);
其余 @Target 如 Field,Class 方法相似
/* * 根据注解类型返回方法的指定类型注解 */ MethodInfo annotation = (MethodInfo) constructor .getAnnotation(MethodInfo.class);
Annotation[] annotations = clazz.getAnnotations(); for (Annotation annotation : annotations) { MethodInfo methodInfo = (MethodInfo) annotation }
/* * 判断构造方法中是否有指定注解类型的注解 */ boolean hasAnnotation = constructor .isAnnotationPresent(MethodInfo.class); if (hasAnnotation) { /* * 根据注解类型返回方法的指定类型注解 */ MethodInfo annotation = (MethodInfo) constructor .getAnnotation(MethodInfo.class); }
public class ParseAnnotation { static String className="com.xujun.animation.test.UserAnnotation"; /** * 简单打印出UserAnnotation 类中所使用到的类注解 该方法只打印了 Type 类型的注解 * * @throws ClassNotFoundException */ public static void parseTypeAnnotation() throws ClassNotFoundException { Class clazz = Class.forName(className); Annotation[] annotations = clazz.getAnnotations(); for (Annotation annotation : annotations) { MethodInfo testA = (MethodInfo) annotation; System.out.println("id= \"" + testA.id() + "\"; name= \"" + testA.name() + "\"; gid = " + testA.gid()); } } /** * 简单打印出UserAnnotation 类中所使用到的方法注解 该方法只打印了 Method 类型的注解 * * @throws ClassNotFoundException */ public static void parseMethodAnnotation() { Method[] methods = UserAnnotation.class.getDeclaredMethods(); for (Method method : methods) { /* * 判断方法中是否有指定注解类型的注解 */ boolean hasAnnotation = method.isAnnotationPresent(MethodInfo.class); if (hasAnnotation) { /* * 根据注解类型返回方法的指定类型注解 */ MethodInfo annotation = method.getAnnotation(MethodInfo.class); System.out.println("method = " + method.getName() + " ; id = " + annotation.id() + " ; description = " + annotation.name() + "; gid= " + annotation.gid()); } } } /** * 简单打印出UserAnnotation 类中所使用到的方法注解 该方法只打印了 Method 类型的注解 * * @throws ClassNotFoundException */ public static void parseConstructAnnotation() { Constructor[] constructors = UserAnnotation.class.getConstructors(); for (Constructor constructor : constructors) { /* * 判断构造方法中是否有指定注解类型的注解 */ boolean hasAnnotation = constructor .isAnnotationPresent(MethodInfo.class); if (hasAnnotation) { /* * 根据注解类型返回方法的指定类型注解 */ MethodInfo annotation = (MethodInfo) constructor .getAnnotation(MethodInfo.class); System.out.println("constructor = " + constructor.getName() + " ; id = " + annotation.id() + " ; description = " + annotation.name() + "; gid= " + annotation.gid()); } } } public static void main(String[] args) throws ClassNotFoundException { parseTypeAnnotation(); parseMethodAnnotation(); parseConstructAnnotation(); } }
运行以上测试程序,将能够看到如下输出结果
id= "0"; name= "type"; gid = class java.lang.Long
method = c ; id = 5 ; description = private method; gid= class java.lang.Long
method = b ; id = 4 ; description = protected method; gid= class java.lang.Long
method = a ; id = 3 ; description = public method; gid= class java.lang.Long
constructor = com.xujun.animationdemo.UserAnnotation ; id = 2 ; description = construct; gid= class java.lang.Long
转载请注明原博客地址:
扫一扫,欢迎关注个人微信公众号 stormjun94(徐公码字), 目前是一名程序员,不只分享 Android开发相关知识,同时还分享技术人成长历程,包括我的总结,职场经验,面试经验等,但愿能让你少走一点弯路。