前言
注解,也被称为元数据,为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。(Java编程思想)
很多文章都是讲述java注解的,而且很多例子虽然有和Android互通的部分,但是Android开发中也扩展了很多单纯Java中没有的注解应用。所以这里主要介绍Android开发中的注解,当然包括Java注解。
目前很多框架开发或者Android开发中都用到了注解,SDK开发中也有很多可以对接口添加限制以规范用户使用的规则,这些都是值得我们去学习的。
Java注解
Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。 Java 语言中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义 Java 标注。
Java内置了三种标准注解,其定义在java.lang中。
- @Override,表示当前的方法定义将覆盖超类中的方法。
- @Deprecated,被此注解标记的元素表示被废弃,如果程序员使用了注解为它的元素,那么编译器会发出警告。
- @SuppressWarnings,关闭不当的编译器警告信息。
这几种注解我们平时开发中肯定经常用到,但是你可能很少看到注解原来的样子。如下为注解的类,可以看到,除了@符号的使用以外,它基本与Java固有语法一致。只是注解上又增加了其他注解。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={
CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
@Target({
TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
那注解的注解又是啥呢,这里就要引出接下来要说的,元注解,专职负责注解其他的注解。
四种元注解
元注解 | 说明 | 取值 |
---|---|---|
@Target | 表示该注解可以用在什么地方 | ElementType.ANNOTATION_TYPE 可以应用于注释类型。 ElementType.CONSTRUCTOR 可以应用于构造函数。 ElementType.FIELD 可以应用于字段或属性。ElementType.LOCAL_VARIABLE 可以应用于局部变量。 ElementType.METHOD 可以应用于方法级注释。 ElementType.PACKAGE 可以应用于包声明。 ElementType.PARAMETER 可以应用于方法的参数。ElementType.TYPE 可以应用于类的任何元素。 |
@Retention | 表示需要在什么级别保存该注解信息 | 1.SOURCE:在源文件中有效(即源文件保留) 2.CLASS:在class文件中有效(即class保留) 3.RUNTIME:在运行时有效(即运行时保留) |
@Documented | 表示将此注解包含在Javadoc中 | 无 |
@Inherited | 表示允许子类继承父类中的注解 | 无 |
经过对元注解的表格进行理解,可以回头看我们平常使用的标准注解Override 、Deprecated 和SuppressWarnings 。可以看到他们分别都由元注解进行了注释,并且我们能够明白,为啥@Override只能用在方法上(@Target),而不能用在类、构造函数、变量上,而@Deprecated就可以用在构造函数、变量、方法、包、参数等,因为其代表的意义就可以表示它能够标注的所有类型都是废弃的元素。
另外,我们需要对Java程序或者Android程序的三个阶段进行解释。我们在as或者idea等IDE开发时的Java源码时期,即SOURCE实际。然后经过gradle或其他构件工具编译,变成了.Class文件,在Android apk中的dex文件中都是.class文件,此时即Retention的Class时期。之后便是程序运行阶段,变成Jvm运行的RUNTIME时期,此时应用是执行状态,如果定义注解为RUNTIME,则此时的注解是保留的。
java的三个标准注解的@Retention,有两个是RetentionPolicy.SOURCE,一个是RetentionPolicy.RUNTIME。从上述表格可以了解,source即源文件保留,即是.java文件中保留。Runtime即运行时有效,即在Android应用在运行时还会存在,当然如果是java程序运行时也保留。可以理解为@Override 注释的方法,只在代码开发时有用即编码时可以覆盖父类方法,编译后和运行中这个注解代表的意义就没有了。
大多数时候,程序员主要是用元注解定义自己的注解,并编写自己的处理器来处理它们,文章最后会简单的写个自定义注解并应用以加深理解。
扩展
上边是经典的Java注解介绍,由于我们的Java开发都是基于JDK的,所以上述源码定义都在JDK的源码中。而由于新的JDK对旧版进行了扩充。
如@Repeatable 即是@since 1.8。 从JDK1.8引入的,可能使用比较少见,笔者也没见过这个的应用目前。但是提这个的目的即任何语法都是供加速开发或者其他目的添加的,只不过我们自定义注解是为了我们自己的逻辑、或者做框架的是为了使用框架的人方便, JDK的开发人员是为了所有Java开发和他们自己方便。所以虽然我们不是定义JDK语言的,但是我们任何人开发都可以使用注解这种方式,为我们的代码和框架服务。注解是不断变化并发展的,当然我们Java或Android开发也是。
pa