Java注解
Java注解
参考
https://blog.csdn.net/briblue/article/details/73824058
https://www.jianshu.com/p/b560b30726d4
Overview
如何理解注解(Annotation), 下面我们先来看一看注解的专业解释
Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。
以上内容来自于: CSDN
如何理解注解
我从参考中的的博客链接中学到了这样的一句话: 不要用专业名词来解释专业名词!
即使参考链接中关于Java的注解已经非常地形象了,但是我还是想用我自己的方式来解释一下。
我们先来理解这一句: Java 注解用于为 Java 代码提供元数据
姚明,我想大家都对他比较熟悉,那么闭上眼睛想一想,我们对姚明有什么印象? 高
,NBA选秀状元
,火箭队球员
,这些修饰词可以说都是关于姚明的标签(TAG)
。姚明一直以来给我的印象是非常的好的,知道后来,有了这么一个表情包:
后来我对,姚明的印象就变成了: 表情包
,高
,NBA选秀状元
...。大姚的表情包太魔性了,以至于直接就充满了我的脑海。
那么想一下不管是表情包
还是高
或者NBA选秀状元
等等,都是对姚明贴上去的标签
。那么反过来理解我们的注解, 注解就是给我们的代码贴上去的标签。
作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。
下面我们继续向下理解
作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。
作为元数据,注解不直接影响你的代码执行,
不管我们给姚明贴上去了什么标签,但是姚明仍然是哪个姚明,还是球迷们眼中的大姚,那么在Java中,不管对代码添加了什么注解,这段代码还是这段代码并不会改变(如果不人为对注解进行处理的话)。如果前半句理解的话,那么后半句就不用多说了吧。
注解的作用
在Java或者Android的许多的框架中都充斥的大量的注解。我想这就不用我多说了吧。
注解的分类
按照存在期间可以分为
- 源码期,此类注解只存在于源码中,编译成为了.class 文件后就不存在了
- 编译期,此类注解在源码和.class文件中都存在,但是在运行期间不存在。如
@Override
- 运行期,在运行阶段还起作用,甚至会影响运行逻辑的注解。像@Autowired自动注入的这样一种注解就属于运行时注解,它会在程序运行的时候把你的成员变量自动的注入进来。
系统的注解
@Override. 用于重写父类的方法
new Thread(new Runnable() {
@Override
public void run() {
}
}).start();
@Deprecated ,将方法标记为不推荐使用
@Deprecated
private void test() {
System.out.println("Test");
}
SuppressWarnings 疏略警告
如上面的test方法,已经被标记为不建议使用,这时候如果使用的话,会产生警告,但是如果这时候还要使用的话是,就可以使用此注解在忽略警告。
@SuppressWarnings("deprecation")
@Override
public void call() {
test();
}
自定义注解
声明一个自定义注解
package annotations.annotations;
//使用@interface 声明一个注解
public @interface Test {
}
//使用刚刚声明的注解
@Test
private void temp() {
}
元注解
在学习自定义注解之前,我们还需要学习一下,元注解。
元注解就是对注解的注解.
@Retention
@Retention 是保留期的意思,该注解的作用是设置注解的保留期一共有三个参数可选.
常量 | 解释 |
---|---|
RetentionPolicy.SOURCE | 在编译之前会被抛弃 |
RetentionPolicy.CLASS | 保留到编译器,在运行时会被抛弃 |
RetentionPolicy.RUNTIME | 保留到运行期 |
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
}
@Documented
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
}
标识会生成该特性的DOC文档。
@Inherited
被Inherited
标示的注解,如果一个类A被它所标识了,A的所有的子类都会继承该特性。
@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
}
@Test
class A {}
class B extends A {}
class C extends B {}
因为基类A被@Test标识而且@Test注解被@Inherited注解,那么A和B也具有该注解.
@Target
Target注解的作用是标识,指定的注解是作用与什么之上的, Target是可以多选的
@Target({ElementType.TYPE, ElementType.METHOD})
@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
}
常量值 | 解释 |
---|---|
ElementType.ANNOTATION_TYPE | 作用于注解 |
ElementType.CONSTRUCTOR | 作用于构造方法 |
ElementType.FIELD | 作用于字段 |
ElementType.LOCAL_VARIABLE | 作用于变量 |
ElementType.METHOD | 作用于方法 |
ElementType.PACKAGE | 作用于包 |
ElementType.PARAMETER | 作用于方法参数 |
ElementType.TYPE | 作用于类/接口/枚举 |
ElementType.TYPE_PARAMETER | 没看懂... |
ElementType.TYPE_USE | 没看懂... |
注解的属性
注解的属性也被称作成员变量,注解中不能有方法,注解的成员变量的定义方式如下
@Target({ElementType.TYPE, ElementType.METHOD})
@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
//通过default方法设置属性的默认值
String tester() default "LD";
String desc() default "Desc";
}
通过反射获取注解的信息
注意只有Runtime存活期的注解才能被反射获取到。
private void getAnnotation() {
Class anClass = AnnotationClass.class;
//获取所有的注解
Annotation[] annotationArray = anClass.getAnnotations();
System.out.println("Array length:" + annotationArray.length);
for (Annotation item : annotationArray) {
//判断注解是否是我们想要的注解
if (item.annotationType() == Test.class) {
Test test = (Test) item;
System.out.printf("这个类的测试者是:%s , 他对本次测试的描述是:%s\r\n", test.tester(), test.desc());
}
}
}
总结
本章的内容到此为止,现在我们对注解也有了一定的了解,在接下来我们将会着手做一个自己的Android的小小的注解框架,用来替代繁琐的findViweById
操作。