首先,什么是注解?@Override是一个注解。它的作用是检查父类中的方法是否被正确改写。标记代码,这是一个重写的方法。1、体现在:检查子类重写的方法名和参数类型是否正确;检查方法private/final/static不能被重写。其实@Override对应用程序没有实际影响,从它的源码就可以看出来。2、主要表现代码的可读性。Override作为Android开发中比较知名的注解,只是注解的一种表现形式。更多时候,注解还有以下作用:降低项目的耦合度。自动完成一些常规代码。自动生成java代码,减少开发人员的工作量。一、注解基础速读1、元注解元注解是java提供的基础注解,负责对其他注解进行注解。如上图所示,Override被@Target和@Retention修饰。它们用于解释其他注解,位于sdk/sources/android-25/java/lang/annotation路径下。元注解包括:@Retention:注解保留的生命周期@Target:注解对象的范围。@Inherited:@Inherited表示修改后的注解是否可以在代理类上继承。@Documented:顾名思义,javadoc的工具是有文档的,一般不用管。@RetentionRetention表示注解的生命周期,对应RetentionPolicy的枚举,表示注解何时生效:SOURCE:只在源码中有效,编译时丢弃,如上面的@Override。CLASS:编译class文件时生效。RUNTIME:只有在运行时才生效。如下图X1所示,编译时会判断com.android.support:support-annotations中的Nullable注解,注解的参数是否为null,具体后续分析。@TargetTarget表示注解的适用范围,对应ElementType枚举,明确注解的有效范围。TYPE:类、接口、枚举、注解类型。FIELD:类成员(构造函数、方法、成员变量)。方法:方法。参数:参数。构造器:构造器。LOCAL_VARIABLE:局部变量。ANNOTATION_TYPE:注释。PACKAGE:包裹声明。TYPE_PARAMETER:类型参数。TYPE_USE:类型使用声明。如上图X1所示,@Nullable可用于注解方法、参数、类成员、注解和包声明。常见示例如下:/***Nullable表示*bind方法的参数target和返回值Data可以为null*/@NullablepublicstaticDatabind(@NullableContexttarget){//dosomeThingandreturnreturnbindXXX(target);}应用@Inherited注解在继承时默认不能继承父类的注解。除非注解声明了@Inherited。同时,Inherited声明的注解只对类有效,对方法/属性无效。如下代码所示,注解类@AInherited声明了Inherited,而注解BNotInherited没有声明Inherited,这是在他们的修改下:类Child继承父类Parent的@AInherited,不继承@BNotInherited;重写的方法testOverride()没有继承Parent的任何注解;testNotOverride()没有被重写,所以注解仍然有效。@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic@interfaceAInherited{Stringvalue();}@Retention(RetentionPolicy.RUNTIME)public@interfaceBNotInherited{Stringvalue();}@AInherited("Inherited")@BNotInherited("NoInherited")publicclassParent{@AInherited("Inherited")@BNotInherited("NoInherited")publicvoidtestOverride(){}@AInherited("Inherited")@BNotInherited("NoInherited")publicvoidtestNotOverride(){}}/***子继承自ParentAInherited注解*BNotInherited不能继承,因为没有@Inherited声明*/publicclassChildextendsParent{/***重写的testOverride不继承任何注解*因为Inherited对方法不起作用*/@OverridepublicvoidtestOverride(){}/***testNotOverride未覆盖*,因此注释AInherited和BNotInherited仍然有效。*/}2.CustomAnnotations2.1RuntimeAnnotations了解元注解后,我们来看看如何实现和使用自定义注解。这里简单介绍一下运行时注解RUNTIME,以及编译时注解CLASS,以备后面分析。首先创建注解遵循:public@interface注解名{方法参数},如下@getViewTo注解:@Target({ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)public@interfacegetViewTo{intvalue()default-1;然后如下图,我们在Activity的成员变量mTv和mBtn中描述注解,在App运行时将findViewbyId获取到的控件通过反射注入到mTv和mBtn中。你熟悉ButterKnife吗?当然,ButterKnife比这更高级。毕竟反射多了影响效率,但是我们理解可以通过注解来注入创建对象,一定程度上可以节省代码。publicclassMainActivityextendsAppCompatActivity{@getViewTo(R.id.textview)privateTextViewmTv;@getViewTo(R.id.button)privateButtonmBtn;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activityviaannotation_main);/生成看法;getAllAnnotationView();}/***解析注解,获取控件*/privatevoidgetAllAnnotationView(){//获取成员变量Field[]fields=this.getClass().getDeclaredFields();for(Fieldfield:fields){try{//判断注解if(field.getAnnotations()!=null){//判断注解类型if(field.isAnnotationPresent(GetViewTo.class)){//允许修改反射属性field.setAccessible(true);GetViewTogetViewTo=field.getAnnotation(GetViewTo.class);//findViewById找到annotation的id,将View注入成员变量field.set(this,findViewById(getViewTo.value()));}}}catch(Exceptione){}}}}2.2Compile-timeannotationsRuntimeannotationsRUNTIME如上面2.1所示,大部分时候都是通过反射在运行时达到预期的效果,非常影响效率。如果不可能实现BufferKnife的每个View注入。其实ButterKnife使用的是编译时注解CLASS,如下图X2.2所示,也就是ButterKnife的@BindView注解。是编译期注解,在编译期生成相应的java代码,实现注入。说到编译期注解,就不得不说到注解处理器AbstractProcessor。大家注意的话,一般第三方注解相关的类库,比如bufferKnike、ARouter,都有一个名为Compiler的Module,如下图X2.3所示。一般都是注解处理器,用于在编译时处理相应的注解。注解处理器(AnnotationProcessor)是javac的一个工具,用于在编译时扫描和处理注解(Annotation)。您可以自定义注解并注册相应的注解处理器来处理您的注解逻辑。如下所示,实现一个自定义注解处理器,至少重写四个方法,并注册你的自定义处理器。具体可以参考下面的代码CustomProcessor。@AutoService(Processor.class),Google提供的自动注册注解,为你生成注册Processor所需的格式文件(com.google.auto相关包)。init(ProcessingEnvironmentenv),初始化处理器,这里一般会得到我们需要的工具。getSupportedAnnotationTypes(),指定注解处理器注册到哪个注解,返回指定的一组支持的注解类。getSupportedSourceVersion(),指定java版本。process(),处理器实际处理逻辑入口。@AutoService(Processor.class)publicclassCustomProcessorextendsAbstractProcessor{/***注解处理器的初始化*一般在这里获取我们需要的工具类*@paramprocessingEnvironment提供工具类Elements,Types和Filer*/@Overridepublicsynchronizedvoidinit(ProcessingEnvironmentenv){super.init(env);//Element表示程序的元素,如包、类、方法等。mElementUtils=env.getElementUtils();//处理TypeMirror工具类,用于获取类信息mTypeUtils=env.getTypeUtils();//Filer可以创建文件mFiler=env.getFiler();//错误处理工具mMessages=env.getMessager();}/***处理器实际处理逻辑入口*@paramset*@paramroundEnvironmentallannotationsset*@return*/@Overridepublicbooleanprocess(Setannoations,RoundEnvironmentenv){//dosomeThing}//指定注解处理器注册到哪个注解,并返回指定的一组支持的注解类。@OverridepublicSet
