在看這篇文章以前對於不知道什麼是註解的建議先看上一篇《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…