我相信註解咱們多多少少的都會接觸到,經常使用的框架Butterknife、Retrofit、ARouter等等都用到了註解,我想你們都會去搜一下什麼是註解了吧。這裏呢就以一個Demo去了解一下自定義註解的使用。java
咱們最多見的註解莫過於@Override了吧,那咱們就去看一下這個註解的代碼。git
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}複製代碼
好了就事論事咱們先看下聲明這個@interface乍一看還覺得是interface呢不過這裏多了個@那就是聲明註解的關鍵字了,這隻要記住就行了。大括號裏面居然沒任何的定義,那就先放一放,咱們來看一下其餘的參數。github
咱們先來照葫蘆畫瓢,定義一個註解類數組
public @interface MyTag {
}複製代碼
註解裏面的定義也是有規定的:bash
註解方法不能帶有參數。框架
註解方法能夠有默認值。ide
註解自己可以包含元註解,元註解被用來註解其餘註解。工具
咱們就來試一下吧!ui
public @interface MyTag {
//聲明返回值類型,這裏可沒有大括號啊,能夠設置默認返回值,而後就直接";"了啊。
String name () default "" ;
int size () default 0 ;
}複製代碼
定義好了註解咱們就來規定咱們這個註解要用到哪裏什麼時候用吧!this
@Target({ElementType.METHOD,ElementType.FIELD})
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTag {
String name () default "" ;
int size () default 0 ;
}複製代碼
這裏呢咱們定義這個註解能夠用在屬性和方法上面,是可繼承的註解,能夠出如今運行時的。由於咱們這邊要模仿一下一下其餘註解框架中註解的用法,我這裏才採用了RetentionPolicy.RUNTIME,由於在運行時咱們採用反射能夠獲得裏面的註解信息。
好了接下來看怎麼使用咱們的這個自定義的註解!
public class HomeActivity extends AppCompatActivity {
@MyTag(name = "BMW",size = 100)
Car car;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
//這裏咱們要首先註冊一下這個類
AnnotationCar.instance().inject(this);
//當程序運行的時候這裏將會輸出該類Car的屬性值。
Log.e("WANG","Car is "+car.toString());
}
}複製代碼
是否是很像咱們使用過的ButterKnife呢,這裏呢咱們再這個Activity裏面定義了一個Car類的屬性,而後再car這個變量上面定義咱們的註解,而且給咱們的註解賦值。而後咱們再onCreate方法裏面先初始化咱們的註解,而後打印Car類的信息,先來看下結果吧
cn.example.wang.routerdemo E/WANG: Car is Car [name=BMW, size=100]複製代碼
這樣咱們的自定義註解就有做用了,好了半天主要的代碼就在那個初始化裏面。
//自定義的類
/**
* Created by WANG on 17/11/21.
*/
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(MyTag.class)) {
MyTag annotation = field.getAnnotation(MyTag.class);
Class<?> type = field.getType();
if(Car.class.equals(type)) {
try {
field.setAccessible(true);
field.set(o, new Car(annotation.name(), annotation.size()));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
}複製代碼
這就說明了爲何註解和反射是同時進入咱們的知識圈裏面的吧!這裏呢咱們先獲取到類裏面全部的屬性,而後去找到被咱們的註解MyTag修飾的那個屬性,而後找到以後,先取咱們註解裏面的值,而後賦值給咱們類裏面的屬性!這樣咱們就用註解去初始化了一個屬性值,嘻嘻這裏就結束了啊!
例子很簡單,看完以後是否是也會寫一個相似ButterKnife的效果了呢,有什麼問題請留言給我,我會實時爲你解答的!