1.注解的定义
官方定义:
Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。
1.1元注解
元注解定义
元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解
- @Target,
- @Retention
- @Documented
- @Inherited
对于注解的跟人理解。举个不恰当的比喻,注解就好比现实的标签。比如高富帅标签,那么元注解就是具体来注解规范这个高富帅标签的内容。比如通过元注解规定这个高富帅标签只能给人使用,动物则不行。比如这个标签只对成年人有效,小孩子会自动忽略等。
1.2元注解具体说明
1.2.1 @Retention
Retention 的英文意为保留期的意思。当 @Retention 应用到一个注解上的时候,它解释说明了这 个注解的的存活时间。 它的取值如下:
- RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
- RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
- RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。
这3个生命周期分别对应于:Java源文件(.java文件) ---> .class文件 ---> 内存中的字节码
由于不同注解使用的时间是不同的,比如动态注解是在运行时获取注解进行相应操作的,静态注解则在编译的时候。所以要精细划分注解的保留时间就需要这个元注解。使用如下:
@Retention(RetentionPolicy.RUNTIME)public @interface TestAnnotation {}复制代码
1.2.2 @Documented
这个元注解肯定是和文档有关。它的作用是能够将注解中的元素包含到 Javadoc 中去
1.2.3 @Target
@Target 指定了注解运用的地方。就看该标签是运用到类还是说方法还是说其他某些地方。 具体@Target取值有
- ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
- ElementType.CONSTRUCTOR 可以给构造方法进行注解
- ElementType.FIELD 可以给属性进行注解
- ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
- ElementType.METHOD 可以给方法进行注解
- ElementType.PACKAGE 可以给一个包进行注解
- ElementType.PARAMETER 可以给一个方法内的参数进行注解
- ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
1.2.4 @Inherited
Inherited 是继承的意思,但是它并不是说注解本身可以继承,而是说如果一个超类被 @Inherited 注解过的注解进行注解的话,那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了超类的注解。
@Inherited@Retention(RetentionPolicy.RUNTIME)@interface Test {}@Testpublic class A {}public class B extends A {}复制代码
注解 Test 被 @Inherited 修饰,之后类 A 被 Test 注解,类 B 继承 A,类 B 也拥有 Test 这个注解。
2.预置注解
Java 默认带了一些注解,平时开发的时候其实也已经在默默使用了。
2.1 @Deprecated
该注解用来标记过时的元素,若某个类或者方法或者元素等被标记了,那么别的引用到那处代码的地方会出现划线,进行标示,提醒使用者,这个代码已经过时,使用要慎重。
@Deprecated public void stopPullLoading() { }复制代码
2.2 @Override
java.lang.Override 是一个marker annotation类型,它被用作标注方法。它说明了被标注的方法重载了父类的方法,起到了断言的作用。如果我们使用了这种annotation在一个没有覆盖父类方法的方法时,java编译器将以一个编译错误来警示。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }复制代码
2.3 @SuppressWarnings
此注解能告诉Java编译器关闭对类、方法及成员变量的警告。 SuppressWarning不是一个marker annotation。它有一个类型为String[]的成员,这个成员的值为被禁止的警告名。对于javac编译器来讲,被-Xlint选项有效的警告名也同样对@SuppressWarings有效,同时编译器忽略掉无法识别的警告名。
@SuppressWarnings(value={ "unchecked","fallthrough"}) public void lintTrap() { /* sloppy method body omitted */ } 复制代码
3.自定义注解
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。
注解参数的可支持数据类型:
- 所有基本数据类型(int,float,boolean,byte,double,char,long,short)
- String类型
- Class类型
- enum类型
- Annotation类型 6.以上所有类型的数组
Annotation类型里面的参数该怎么设定: 第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型; 第二,参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String; 第三,如果只有一个参数成员,最好把参数名称设为"value",后加小括号.例:下面的例子FruitName注解就只有一个参数成员。
简单的自定义注解和使用注解实例:
package annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 水果名称注解 * @author wangsheng * */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FruitName { String value() default ""; } 复制代码
4.注解的作用
个人开发时注解的作用:
- 通过注解标注让系统在编译或者运行时来处理某些重复事件,如View的id绑定,点击事件绑定等
- 信息收集,比如被注解的类被收集注册到一个集合,以便于监听处理
- 其他一些未使用过的功能(接下来想到补充)
5.运行时注解
一般在运行时反射获取到注解的内容,然后进行相应的操作,比如绑定id等。 参考了解:
6.编译时注解
需要使用到APT,在代码编译阶段根据注解完成相应代码的添加,由于在编译阶段完成了相关工作,所以影响比动态注解小,性能更好。
(留坑接下来写文章填)