在看这篇文章以前对于不知道什么是注解的建议先看上一篇《JAVA注解》 穿越门 ,若是知道的话就能够跳过了。java
首先在讲运行时注解以前,有必要先说一下注解其存在周期。对于JAVA自定义注解其存在的周期主要和其元注解android
@Retention
复制代码
的赋值有关。git
元注解的赋值一共有以下三种:github
这3个生命周期分别对应于:Java源文件(.java文件) ---> .class文件 ---> 内存中的字节码bash
咱们的运行时注解对应标注为ide
@RetentionPolicy.RUNTIME
复制代码
的注解,即代码在内存中运行时可获取处理的注解。post
本次自定义注解目标为实现一个汽车类信息注解(CarInfo),该注解做用于Car类的值上。可实现不使用set方法,经过注解给该值添加对象并完成初始化的功能。性能
实现该注解第一步需在annotation包下自定义一个***CarInfo***的注解,代码以下ui
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface CarInfo {
String name () default "" ;
int size () default 0 ;
}
复制代码
从元注解的信息可知,该注解可做用于值,生命周期到运行时一直存在,该注解主要包括车名和车数量两个内容。this
在MainActivity类中定义一个Car类的值,而后在他上面添加CarInfo注解,并添加name和size相关属性。添加完该注解之后,咱们在代码运行时就能获取car值上的注解内容了。
@CarInfo(name = "BMW",size = 100)
Car car;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//这里咱们要首先注册一下这个类
AnnotationCar.instance().inject(this);
//当程序运行的时候这里将会输出该类Car的属性值。
Log.e("WANG","Car is "+car.toString());
}
复制代码
运行时注解核心的内容就是注解处理。 注解处理有两个核心问题:
对于问题一,答案就是经过反射去获取注解。 思路大概以下:
对于问题二,具体问题须要具体分析,不过通常可把时机放早点。我放在onCreate方法内。
no code no truth
注解处理相关代码
public class AnnotationCar {
private static AnnotationCar annotationCar;
public static AnnotationCar instance(){
synchronized (AnnotationCar.class){
if(annotationCar == null){
annotationCar = new AnnotationCar();
}
return annotationCar;
}
}
public void inject(Object o){
Class<?> aClass = o.getClass();
Field[] declaredFields = aClass.getDeclaredFields();
for (Field field:declaredFields) {
if(field.getName().equals("car") && field.isAnnotationPresent(CarInfo.class)) {
CarInfo annotation = field.getAnnotation(CarInfo.class);
Class<?> type = field.getType();
if(MainActivity.Car.class.equals(type)) {
try {
field.setAccessible(true);
field.set(o, new MainActivity.Car(annotation.name(), annotation.size()));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
}
复制代码
注解注入过程
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//这里咱们要首先注册一下这个类
AnnotationCar.instance().inject(this);
//当程序运行的时候这里将会输出该类Car的属性值。
Log.e("WANG","Car is "+car.toString());
}
复制代码
运行结果
2018-12-25 17:07:09.935 12026-12026/android.weifeng.com.annotationtest E/WANG: Car is Car{name='BMW', size=100}
复制代码
获取到了注解中的内容,注解成功。
示例代码地址 :github.com/yitianbu/An…