概述
记得之前有个iOS问过我 @BindView 是什么,我说是注解,他问我什么是注解,我回答说相当于一种接口。他后面好像还问一些关于注解的问题,我一时语塞,竟然发现我天天使用的注解,要解释它的时候竟然有种说不上来的感觉。
今天想把关于注解的知识归纳一下:
简介
定义
注解是Java的一种类型,相当于class,interface一样,基本作用是作用和解释Java代码
优点
简化使用,降低代码量
注解分类
Java内置注解
- 定义
JDK已有的注解,包括以下几类:
@Deprecated:过时注解,标记已过时的方法和类等
@Override:复写
@SuppressWarnings:阻止警告注解,可忽略警告
@SafeVarargs:参数安全型注解
@Functionallnterface:函数式接口注解
元注解
- 定义
相当与一种Tag标识,是Android的内置注解 - 作用
作用于注解,解释注解 - 类型
可分以下几种类型:
@Retention:保留注解,说明注解的生命周期,例如:1
2
3
4//用Retention来解释,RetentionPolicy.RUNTIME说明注解有生命周期
(RetentionPolicy.RUNTIME)
public TestAnnotation{//定义TestAnnotation注解
}
@Documented:文档注解,将注解中的元素包含到Javadoc文档中,使用与上面类似1
2
3
public TestAnnotation{//定义TestAnnotation注解
}
@Target:目标注解,限定了注解作用的目标范围,包括类方法等。
@Inherited:集成注解,使一个被@Inherited注解的注解作用的类的子类可以继承该类的注解,例如:1
2
3
4
5
6
7
8
9
10
11
public TestAnnotation{
}
... ...
class A{
}
... ...
class B extends A{
}
//B集成了A那么且B没有被其他注解标记,那么B也被@TestAnnotation标记了
@Repearable:可重复注解,让作用的注解可以取多个值
自定义注解
我们知道注解是一种特殊的接口,所以定义起来跟普通接口相似,1
2
3
4
5
6
7public TestAnnotation{
//注解只有成员变量,即两个属性,没有方法
//所以该注解的两个属性是no和name。方法名等于属性名
int no;
String name() default "Hello Annotation";
//default的意思是属性name默认返回的是Hello Annotation
}
定义完成后开始使用1
2
3
4
5 (RetentionPolicy.RUNTIME)
public TestAnnotation {
int id();
String getViewNo() default "HelloWord";
}
用单元测试来试下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39public class TestAnnotationActivityTest {
100,getViewNo = "HelloAnnotation") (id =
private int code1;
200,getViewNo = "HelloAnnotation") (id =
private int code2;
public void onCreate() {
iniData();
}
private void iniData(){
setAPT();
Log.e("TestAnnotation","code1 = "+code1);
Log.e("TestAnnotation","code2 = "+code2);
}
private void setAPT() {
//获得成员变量
Field[] fields = this.getClass().getDeclaredFields();
for (Field field : fields) {
try {
//判断注解
if (field.getAnnotations() != null) {
//确定注解类型
if (field.isAnnotationPresent(TestAnnotation.class)) {
//允许修改反射属性
field.setAccessible(true);
TestAnnotation getView = field.getAnnotation(TestAnnotation.class);
Log.e("TestAnnotation",getView.getViewNo());
Log.e("TestAnnotation",getView.id()+"");
field.set(this,getView.id());//将id赋值给注解成员
}
}
} catch (Exception e) {
}
}
}
}
即使没有对code12进行初始化,也能将注解的属性复制给变量
结果
总结
注解应用的十分频繁,开发使用的第三方框架都有注解的部分,能更好的解释代码,减少代码量,降低耦合等。都是使用注解的优点。