我相信註解咱們多多少少的都會接觸到,經常使用的框架Butterknife、Retrofit、ARouter等等都用到了註解,我想你們都會去搜一下什麼是註解了吧。這裏呢就以一個Demo去了解一下自定義註解的使用。java
咱們最多見的註解莫過於@Override了吧,那咱們就去看一下這個註解的代碼。git
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}複製代碼
好了就事論事咱們先看下聲明這個@interface乍一看還覺得是interface呢不過這裏多了個@那就是聲明註解的關鍵字了,這隻要記住就行了。大括號裏面居然沒任何的定義,那就先放一放,咱們來看一下其餘的參數。github
咱們先來照葫蘆畫瓢,定義一個註解類數組
public @interface MyTag {
}複製代碼
註解裏面的定義也是有規定的:bash
註解方法不能帶有參數。markdown
註解方法能夠有默認值。框架
註解自己可以包含元註解,元註解被用來註解其餘註解。ide
咱們就來試一下吧!工具
public @interface MyTag { //聲明返回值類型,這裏可沒有大括號啊,能夠設置默認返回值,而後就直接";"了啊。 String name () default "" ; int size () default 0 ; }複製代碼
定義好了註解咱們就來規定咱們這個註解要用到哪裏什麼時候用吧!oop
@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的效果了呢,有什麼問題請留言給我,我會實時爲你解答的!