地址:https://juejin.im/post/5a14158df265da432c237bfc
声明:本文是那个人原创,已获其授权发布,未经原作者允许请勿转载
一 前言
我相信注解我们多多少少的都会接触到,常用的框架Butterknife、Retrofit、ARouter等等都用到了注解,我想大家都会去搜一下什么是注解了吧。这里呢就以一个Demo去了解一下自定义注解的使用。
二 知识准备
我们最常见的注解莫过于@Override了吧,那我们就去看一下这个注解的代码。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
好了就事论事我们先看下声明这个@interface乍一看还以为是interface呢不过这里多了个@那就是声明注解的关键字了,这只要记住就好了。大括号里面竟然没任何的定义,那就先放一放,我们来看一下其他的参数。
三 自定义注解
我们先来照葫芦画瓢,定义一个注解类
public @interface MyTag {
}
注解里面的定义也是有规定的:
我们就来试一下吧!
public @interface MyTag {
//声明返回值类型,这里可没有大括号啊,可以设置默认返回值,然后就直接";"了啊。
String name () default "" ;
int size () default 0 ;
}
定义好了注解我们就来规定我们这个注解要用到哪里何时用吧!
@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的效果了呢,有什么问题请留言给我,我会实时为你解答的!