版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1342032
为什么要写这一系列的博客呢?
因为在 Android 开发的过程中, 泛型,反射,注解这些知识进场会用到,几乎所有的框架至少都会用到上面的一两种知识,如 Gson 就用到泛型,反射,注解,Retrofit 也用到泛型,反射,注解 。学好这些知识对我们进阶非常重要,尤其是阅读开源框架源码或者自己开发开源框架。
至于关于编译时的注解,待下篇博客的时候会结合例子讲解一下,目前我也正在学习当中
提到注解,大多数人应该都不默认,在我们程序中见到的@Override,@Deprected,@SupressWarnings等等,这些都是注解,只不过是系统自己封装好的,而我们平时比较少去深入理解是怎样实现的?
Annotation(注解)就是Java提供了一种元程序中的元素关联任何信息和着任何元数据(metadata)的途径和方法。Annotion(注解)是一个接口,程序可以通过反射来获取指定程序元素的Annotion对象,然后通过Annotion对象来获取注解里面的元数据。
根据注解参数的个数,我们可以将注解分为三类:
根据注解使用方法和用途,我们可以将Annotation分为三类:
元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它annotation类型作说明。Java5.0定义的元注解:
元注解 解析说明
元数据从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();
}
String name() default "xujunTest";
/**
* 这个类专门用来测试注解使用
* @author xujun
*/
@MethodInfo(name="type",gid=Long.class) //类成员注解
public class UserAnnotation {
@MethodInfo(name="param",id=1,gid=Long.class) //类成员注解
private Integer age;
@MethodInfo (name="construct",id=2,gid=Long.class)//构造方法注解
public UserAnnotation(){
}
@MethodInfo(name="public method",id=3,gid=Long.class) //类方法注解
public void a(){
Map<String,String> m = new HashMap<String,String>(0);
}
@MethodInfo(name="protected method",id=4,gid=Long.class) //类方法注解
protected void b(){
Map<String,String> m = new HashMap<String,String>(0);
}
@MethodInfo(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
转载请注明原博客地址: