我相信注解我们多多少少的都会接触到,常用的框架Butterknife、Retrofit、ARouter等等都用到了注解,我想大家都会去搜一下什么是注解了吧。这里呢就以一个Demo去了解一下自定义注解的使用。
我们最常见的注解莫过于@Override了吧,那我们就去看一下这个注解的代码。
- @Target(ElementType.METHOD)
- @Retention(RetentionPolicy.SOURCE)
- public @interface Override {
- }
好了就事论事我们先看下声明这个@interface乍一看还以为是interface呢不过这里多了个@那就是声明注解的关键字了,这只要记住就好了。大括号里面竟然没任何的定义,那就先放一放,我们来看一下其他的参数。
* @Target()
@Target说明了Annotation所修饰的对象范围,也就是我们这个注解是用在那个对象上面的:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)取值(ElementType)是来源于Java.lang.annotation.ElementType中的枚举类型元素:
(1).CONSTRUCTOR:用于描述构造器
(2).FIELD:用于描述域
(3).LOCAL_VARIABLE:用于描述局部变量
(4).METHOD:用于描述方法
(5).PACKAGE:用于描述包
(6).PARAMETER:用于描述参数
(7).TYPE:用于描述类、接口(包括注解类型) 或enum声明
* @Retention()
@Retention定义了该Annotation被保留的时间长短:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。使用这个meta-Annotation可以对 Annotation的“生命周期”限制。
作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)取值(RetentionPoicy)来源于java.lang.annotation.RetentionPolicy的枚举类型值:
(1).SOURCE:在源文件中有效(即源文件保留)
(2).CLASS:在class文件中有效(即class保留)
(3).RUNTIME:在运行时有效(即运行时保留)
* @Documented
@Documented用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。
* @Inherited:
@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。 注意:@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。当@Inherited annotation类型标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API增强了这种继承性。如果我们使用java.lang.reflect去查询一个@Inherited annotation类型的annotation时,反射代码检查将展开工作:检查class和其父类,直到发现指定的annotation类型被发现,或者到达类继承结构的顶层。
我们先来照葫芦画瓢,定义一个注解类
- 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的效果了呢,有什么问题请留言给我,我会实时为你解答的!
感觉对你有帮助请点个赞啊~
欢迎关注 我的掘金
欢迎关注 我的简书
欢迎关注 我的csdn
来源: http://blog.csdn.net/jsonchumpklutz/article/details/78599277