注解深入浅出(一注解 Annotations)
Posted 持续学习刻意练习
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了注解深入浅出(一注解 Annotations)相关的知识,希望对你有一定的参考价值。
第二章注解深入浅出
一、注解 Annotations
1.1 注解
注解是一种将元数据附加到代码中的方法。
注解(Annotation),也叫做元数据,一种代码级别的说明。 它是 JDK 1.5 及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明、注解。
Java 注解:声明注解需要在类前面使用 @interface 关键字:
public @interface MyAnnotation
Kotlin 注解:声明注解需要在类前面使用 annotation 关键字:
annotation class MyAnnotation
android 注解的好处:
- 简化代码,提高开发效率(不一定提高运行效率)
- 更早的发现程序的问题或者错误
- 更好的增加代码的描述能力
- 更加利于我们的一些规范约束
- 提供解决问题的更优解
1.2 元注解
元注解是用来定义其他注解的注解,简单来说,就是注解上的注解。
元注解共有四种:@Rentention、@Target、@Inherited、@Documented。
@Retention:注解保留的声明周期,默认值为 CLASS。对应 RetentionPolicy 的枚举,表示注解在何时生效,可选值有三种
- SOURCE:只在源码中可用(当 Java 文件编译成 Class 文件的时候,注解被遗弃)
- CLASS:在源码和字节码中可用(Jvm 加载 Class 文件的时候被遗弃,这是默认的声明周期)
- RUNTIME:在源码、字节码和运行时均可用(Jvm 加载到 Class 文件之后,仍然存在)
SOURCE < CLASS < RUNTIME,前者能作用的地方后者一定也能作用。
@Target:注解对象的作用范围,对应 ElementType 枚举,明确了注解的有效范围。ElementType 枚举中包括:
- TYPE:类、接口、枚举、注解类型
- FIELD:类成员(构造方法、方法、成员变量)
- METHOD:方法
- PARAMETER:方法参数
- CONSTRUCTOR:构造函数
- LOCAL_VARIABLE:局部变量
- ANNOTATION_TYPE:注解
- PACKAGE:包
- TYPE_PARAMETER:类型参数
- TYPE_USE:类型使用声明
@Inherited:注解是否可以被继承,默认为 false。用 @Inherited 声明出来的注解只对类有效,对方法/属性无效。
@Document:是否会保存到 Javadoc 文档中。
现在来看下 @Override 注解的源码:
package java.lang;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
public @interface Override
分析一下,
@Retention(RetentionPolicy.SOURCE):表示 @Override 注解只在源码中使用,
@Target(ElementType.METHOD):表示 @Override 注解作用的范围在方法中,也就是用来修饰方法的。
1.3 自定义注解
自定义注解的时候,需要使用到元注解来定义我们自定义的注解。
举个例子讲解。
package com.example.demo;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME)
@Target(FIELD)
public @interface TestAnnotation
String value();
String[] value2() default "value2";
注解值的写法:类型 参数名() default 默认值;
其中默认值是可选的,可以定义,也可以不定义。
处理运行时注解
Rentention 的值为 RUNTIME 时,注解会保留到运行时,因此使用反射来解析注解。
还是用上一步的注解 @TestAnnotation,解析示例如下:
package com.example.demo;
import java.lang.reflect.Field;
public class Demo
@TestAnnotation("Hello Annotation")
private String testAnnotation;
public static void main(String[] args)
try
// 获取要解析的类
Class clazz = Class.forName("myAnnotaiton.Demo");
// 拿到所有 Filed
Field[] declaredFields = clazz.getDeclaredFields();
for (Field field : declaredFields)
// 获取 Field 上的注解
TestAnnotation testAnnotation = field.getAnnotation(TestAnnotation.class);
if (null != testAnnotation)
// 获取注解值
String value = testAnnotation.value();
System.out.println("value = " + value);
catch (ClassNotFoundException e)
e.printStackTrace();
以上是关于注解深入浅出(一注解 Annotations)的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate 注解 (Annotations 三)多对一双向注解
P4 开发实践 — 编程基础 — Annotations 注解
P4 开发实践 — 编程基础 — Annotations 注解
P4 开发实践 — 编程基础 — Annotations 注解