You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@IntDef({VISIBLE, INVISIBLE, GONE})
@Retention(RetentionPolicy.SOURCE)
public @interface Visibility {}
public static final int VISIBLE = 0x00000000;
public static final int INVISIBLE = 0x00000004;
public static final int GONE = 0x00000008;
public void setVisibility(@Visibility int visibility) {
setFlags(visibility, VISIBILITY_MASK);
}
2、RetentionPolicy.RUNTIME
运行时注解的定义如下:
// 适用类、接口(包括注解类型)或枚举
Retention(RetentionPolicy.RUNTIME)
Target(ElementType.TYPE)
public @interface ClassInfo {
String value();
}
// 适用field属性,也包括enum常量
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FieldInfo {
int[] value();
}
// 适用方法
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MethodInfo {
String name() default "long";
int age() default 27;
}
定义一个测试类来使用这些注解:
/**
* 测试运行时注解
*/
@ClassInfo("Test Class")
public class TestRuntimeAnnotation {
@FieldInfo(value = {1, 2})
public String fieldInfo = "FiledInfo";
@MethodInfo(name = "BlueBird")
public static String getMethodInfo() {
return return fieldInfo;
}
}
【说在前面的话】
看懂很多开源库
,如Arouter, dagger,Butter Knife等,不得不先看懂注解;#一、什么是注解
java.lang.annotation,接口 Annotation,在JDK5.0及以后版本引入。
注解是代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。通过使用Annotation,开发人员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充的信息。代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证、处理或者进行部署。
Annotation不能运行,它只有成员变量,没有方法。Annotation跟public、final等修饰符的地位一样,都是程序元素的一部分,Annotation不能作为一个程序元素使用。
其实大家都是用过注解的,只是可能没有过深入了解它的原理和作用,比如肯定见过
@Override
,@Deprecated
等。##1、注解的作用
注解将一些本来重复性的工作,变成程序自动完成,简化和自动化该过程。比如用于生成Java doc,比如编译时进行格式检查,比如自动生成代码等,用于提升软件的质量和提高软件的生产效率。
##2、注解都有哪些
平时我们使用的注解有来自JDK里包含的,也有Android SDK里包含的,也可以自定义。
2.1、JDK定义的元注解
Java提供了四种元注解,专门负责新注解的创建工作,即注解其他注解。
@target
定义了Annotation所修饰的对象范围,取值:
ElementType.CONSTRUCTOR
:用于描述构造器ElementType.FIELD
:用于描述域ElementType.LOCAL_VARIABLE
:用于描述局部变量ElementType.METHOD
:用于描述方法ElementType.PACKAGE
:用于描述包ElementType.PARAMETER
:用于描述参数ElementType.TYPE
:用于描述类、接口(包括注解类型) 或enum声明@retention
定义了该Annotation被保留的时间长短,取值:
-
RetentionPoicy.SOURCE
:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;用于做一些检查性的操作,比如@Override
和@SuppressWarnings
-
RetentionPoicy.CLASS:
注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;用于在编译时进行一些预处理操作,比如生成一些辅助代码(如ButterKnife
)-
RetentionPoicy.RUNTIME
:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;用于在运行时去动态获取注解信息。@documented
标记注解,用于描述其它类型的注解应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化,不用赋值。
@inherited
标记注解,允许子类继承父类的注解。 这里一开始有点理解不了,需要断句一下,允许子类继承
父类的注解
。示例:这样类Test2其实也有注解@sample 。
正常写法
省略value的写法(只有成员名称是value时才能省略)
成员类型是数组,只赋值一个元素的简写
** 2.2 JDK内置的其他注解 **
@Override、@Deprecated、@SuppressWarnings、@SafeVarargs、@FunctionalInterface、@Resources
等。** 2.3 Android SDK内置的注解 **
Android SDK 内置的注解都在包com.android.support:support-annotations里,下面以'com.android.support:support-annotations:25.2.0'为例
@AnimRes @AnyRes @ArrayRes @AttrRes @BoolRes @ColorRes等
@AnyThread @BinderThread @MainThread @UiThread @WorkerThread
@NonNull @Nullable
@FloatRang @IntRange
@IntDef @StringDef
@CallSuper @CheckResult @ColorInt @Dimension @Keep @Px @RequiresApi @RequiresPermission @RestrictTo @Size @VisibleForTesting
二、自定义注解
使用收益最大的,还是需要根据自身需求自定义注解。下面依次介绍三种类型的注解自定义示例:
1、RetentionPolicy.SOURCE
一般函数的参数值有限定的情况,比如View.setVisibility 的参数就有限定,可以看到View.class源码里
除了
IntDef
,还有StringDef
2、RetentionPolicy.RUNTIME
运行时注解的定义如下:
定义一个测试类来使用这些注解:
使用注解:
所做的操作都是通过反射获取对应元素,再获取元素上面的注解,最后得到注解的属性值。因为涉及到反射,所以运行时注解的效率多少会受到影响,现在很多的开源项目使用的是编译时注解。
3、RetentionPolicy.CLASS
** 3.1 添加依赖 **
在整个工程的 build.gradle 中添加
android-apt
的依赖** 3.2 定义要使用的注解 **
建一个Java库来专门放注解,库名为:annotations
定义注解
** 3.3 定义注解处理器 **
另外建一个Java库工程,库名为:processors
这里必须为Java库,不然会找不到javax包下的相关资源
build.gradle 要依赖以下:
其中,
auto-service 自动用于在 META-INF/services 目录文件夹下创建 javax.annotation.processing.Processor 文件;
javapoet用于产生 .java 源文件的辅助库,它可以很方便地帮助我们生成需要的.java 源文件
示例:
** 3.4 在代码中使用定义的注解 **:
需要依赖上面的两个java库annotations和processors
编译后就会生成指定包名的指定文件,如图:
** 3.5 注解处理器的辅助接口 **
在自定义注解处理器的初始化接口,可以获取到以下4个辅助接口:
Types
: Types是一个用来处理TypeMirror的工具Elements
: Elements是一个用来处理Element的工具Filer
: 一般我们会用它配合JavaPoet来生成我们需要的.java文件Messager
: Messager提供给注解处理器一个报告错误、警告以及提示信息的途径** 3.5 带有注解的库提供给第三方 **
一般使用编译时注解的库,都会有三个module:
然后第三方使用时,可以像如下这样依赖:
sample project见AnnotationSample
The text was updated successfully, but these errors were encountered: