一分钟秒懂注解,快速记忆神器
各位开发童鞋,注解这个东西我们肯定每天都能看见,也许有时候看的太多了到是会忽略注解这东西具体是如何工作的。今天在这里用最短的篇幅快速讲解下注解的原理,对这块记的不太清楚的同学也可以再次看看,下次有人详细问这块的话不至于一知半解。
元注解
1 | @Retention(RetentionPolicy.RUNTIME) |
把注解讲完这一个栗子就够了,可以看到自定义注解里也会有注解存在,给自定义注解使用的注解就是元注解:
- @Rentention Rentention用来标记自定义注解的有效范围,一般就三种:RetentionPolicy.SOURCE 只在源代码中保留 一般都是用来增加代码的理解性或者帮助代码检查之类的,比如我们的Override;RetentionPolicy.CLASS 默认的选择,能把注解保留到编译后的字节码class文件中,仅仅到字节码文件中,运行时是无法得到的;RetentionPolicy.RUNTIME,注解不仅 能保留到class字节码文件中,还能在运行通过反射获取到,一般我们真正用到的都是这种。(这个点在面试过程中有可能被问到,记性不好的赶紧收藏一下,下次要面试之前可以快速浏览一遍半个月都忘不了)。
- @Target 说明注解使用的地方,值很多,不一一细说了
- @Documented 使用了@Documented的可以在javadoc中找到
- @Interited 可继承性的标识,使用了Interited表示注解里的内容可以被子类继承,比如父类中某个成员使用了上述@From(value),From中的value能给子类使用到。
关键字和注解内容
- @interface 这个东西在声明注解的时候必须得使用,用@interface就意味着这个东西已经继承了java.lang.annotation.Annotation,也说明了它是一个注解。
然后就是注解里的内容了,上述From中定义了两项内容,所以这个注解可以这么用:@From(1),或者是@From(value = 1,canBuNull = true)或者是@From(canBuNull = true),那么能不能写成@From(true)呢。。当然不能,当括号里内容不以键值对形式出现的话默认是使用value的。
工作原理
最再说说注解的工作原理吧。也很简单,一般我们自定义的RetentionPolicy.RUNTIME比较多,就说一下它的大概原理吧,其实可以把这种注解理解成一个可以接收参数的方法,只不过这个方法的处理逻辑是别人事先写好的,使用了RetentionPolicy.RUNTIME的注解括号里提供的参数都是可以通过反射拿到,举个很简单的栗子,就拿下面来说:1
2From(R.id.tvLogin)
TextView tvLogin;
用这个From来接受一个id最后给tvLogin注入TextView的实例,我们在定义了这个@From注解后,再提供一个方法,在需要注入的时机调用(eg:OnCreate())1
2
3
4
5
6
7
8
9
10
11void onCreate(){
Injection.inject(this);
}
class Injection{
void inject(){
int id = getIDFromReflection();//通过反射获得@From(id)中的id
TextView tv = getMemberFormReflection();//通过反射得到添加了@From注解的需要被注入的View
tv = (TextView)xxx.findViewById(id);
}
}
就这样,通过From就轻松得省去了一大堆findViewById的方法,说到底,注解最大的好处就是让代码变得简洁明了然后还能减少一些重复的机械劳动,解放双手。
其实注解就那么点东西,很简单的,平时如果使用的太多而而忽略了它的原理就有点不太靠谱了,我个人觉得做到理解了就行,很多内容全要记下来也是不可能的,只要明白了原理,太细节的地方用的时候再来查完全都不是问题了。