下面的代码片段相信有过Android开发经验的朋友都会非常的熟悉.1
2
3
4
5
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
其中OnCreate()
方法前的@Override
便是今天的主角,没错它就是Java的注解Annotation.
什么是Annotation
简单的说注解就是给Java代码标上标签,让Java虚拟机知道该如何处理被标注的代码.
Java的内置Annotations
Java的注解分为:
- 普通注解(用于注解:类,方法,变量,参数,包)
- @Override: 标注的方法为复写方法
- @Deprecated: 标注的方法已过时,被弃用
- @SuppressWarnings: 标注的方法被编译时忽略其他的注解警告
- @SafeVarargs: 修饰”堆污染”警告
- @FunctionalInterface: 修饰函数式接口
- 元注解(用于标注注解的注解)
- @Retention: 注解保留策略
- RetentionPolicy.SOURCE: 停留在Java源文件,被编译器丢弃
- RetentionPolicy.CLASS: 停留在class文件中,但被虚拟机丢弃
- RetentionPolicy.RUNTIME: 内存中的字节码,在运行时保留,可通过反射获取相关信息
- @Target: 注解修饰目标
- ElementType.CONSTRUCTOR: 构造器声明
- ElementType.FIELD: 成员变量,对象,属性
- ElementType.LOCAL_VARIABLE: 局部变量声明
- ElementType.METHOD: 方法声明
- ElementType.PACKAGE: 包声明
- ElementType.PARAMETER: 参数声明
- ElementType.TYPE: 类,接口(包括注解类型),枚举声明
- @Documented: 注解文档提取
- @Inherited: 注解继承声明
- @Retention: 注解保留策略
自定义注解
废话少说,下面我们通过注解来实现对一个person的信息注入:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/**
* 简单的Person类
**/
public class Person {
String name;
int age;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public void display()
{
System.out.println(name+" "+age);
}
}
下面是一个自定义注解,声明了一个用于注解变量的运行时注解1
2
3
4
5
6//运行时保留,可通过反射获取相关信息 (RetentionPolicy.RUNTIME)
//用于注解成员变量 (ElementType.FIELD)
public PersonAnnotation {
String name() default ""; //Person的名字,默认值为空
int age(); //Person的年龄,没有默认值
}
之后我们需要对我们的注解进行处理,让它能够对我们使用了PersonAnnotation
标注的Person
成员变量进行自动赋值.这部分工作由下面的AnnotationPaser
类完成.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33public class AnnotationParser {
/**
* 完成对注解的处理
* @param object 持有注解目标的对象
**/
public static void parse(Object object)
{
Person p;
Class<?> clazz = object.getClass();
//获取Object对象的所有声明变量
Field[] fields = clazz.getDeclaredFields();
//遍历成员变量
for(Field f:fields)
{
//检查成员变量是否被PersonAnnotation注解修饰
if(f.isAnnotationPresent(PersonAnnotation.class)){
PersonAnnotation personAnnotation=f.getAnnotation(PersonAnnotation.class);
int age = personAnnotation.age();
String name = personAnnotation.name();
p = new Person(age,name);
//设置访问权限
f.setAccessible(true);
try {
//设置属性
f.set(object,p);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
完成了对注解的处理后,我们的自定义注解就可以使用了.1
2
3
4
5
6
7
8
9
10public class Test {
"kevin",age = 20) (name =
Person person;
public static void main(String[] args) {
Test t=new Test();
AnnotationParser.parse(t);
t.person.display();
}
}
运行结果:1
kevin 20