我相信注解咱们多多少少的都会接触到,经常使用的框架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的效果了呢,有什么问题请留言给我,我会实时为你解答的!