Java基础(3)-注解总结

Java注解深入解析
本文详细阐述了Java注解的用途、实现原理及其核心组成部分,包括元注解、注解成员变量、注解数据提取方法及自定义注解的创建过程。

一.注解的用处和实现原理

1.用处

注解Annotation的出现是为了简化Xml配置带来的复杂性,注解是一种元数据(描述数据的数据),它是一种在运行时被读取或写入的一种特殊标记,用以描述数据的特性或者读取到数据的值。

2.实现原理

注解的实现原理和动态代理一样都是基于反射。

二.元注解

元注解是Java中用于实现自定义注解的元数据,用户自定义的注解都需要通过元注解来进行描述才能生效。

1.@Retention

用于指定被修饰的Annotation可以保留多长时间,只能修饰Annotation定义。@Retention包含一个RetentionPolicy类型的value成员变量,使用@Retention必须为该value成员变量指定值。value成员变量的值有3个选择:

  • RetentionPolicy.CLASS:编译器将把Annotation记录在class文件中。当运行java程序时,JVM不可获取Annotation信息。(默认值)
  • RetentionPolicy.RUNTIME:编译器将把Annotation记录在class文件中。当运行java程序时,JVM也可获取Annotation信息,程序可以通过反射获取该Annotation信息。
  • RetentionPolicy.SOURCE:Annotation只保留在源代码中(.java文件中),编译器直接丢弃这种Annotation。
//注解保留到运行时,可以通过反射获取到该注解
@Retention(RetentionPolicy.RUNTIME)
public @interface DemoAnnotation {}
2.@Target

用于指定被修饰到Annotation可以修饰哪些类型。

  • @Target(ElementType.ANNOTATION_TYPE):指定该该策略的Annotation只能修饰Annotation.
  • @Target(ElementType.TYPE) //接口、类、枚举、注解
  • @Target(ElementType.FIELD) //成员变量(字段、枚举的常量)
  • @Target(ElementType.METHOD) //方法
  • @Target(ElementType.PARAMETER) //方法参数
  • @Target(ElementType.CONSTRUCTOR) //构造函数
  • @Target(ElementType.LOCAL_VARIABLE)//局部变量
  • @Target(ElementType.PACKAGE) ///修饰包定义
  • @Target(ElementType.TYPE_PARAMETER) //java8新增
  • @Target(ElementType.TYPE_USE) ///java8新增
3.@Documented

用于指定被修饰的Annotation将被javadoc工具提取成文档。即说明该注解将被包含在javadoc中。

4.@Inherited

用于指定被修饰的Annotation具有继承性。即子类可以继承父类中的该注解。

三.注解成员变量

在注解中可以设置注解的成员变量,以便之后获取到该注解的特定所需数据:

/*
 * @Author ARong
 * @Description 使用@interface关键字定义注解
 * @Param
 * @return
 **/
// 注解保留到运行时,可以被反射所解析
@Retention(RetentionPolicy.RUNTIME)
// 注解修饰对对象可以是类、接口与枚举类型
@Target(ElementType.TYPE)
// 注解可以被编入文档
@Documented
// 注解可以被继承
@Inherited
public @interface DemoAnnotation {
    // 以方法签名定义注解的成员变量
    int id() default 1;// 定义默认值
    String name();
}
  • 使用注解
/**
 * @Auther: ARong
 * @Description: 测试自定义注解
 */
@DemoAnnotation(id = 6, name = "HelloWorld")
public class TestDemoAnnotation {
}

四.提取注解数据

使用注解的最主要目的之一就是在运行时提取注解中所含有的数据,以用于完成其他的操作。那么要如何获取到注解的数据呢?首先要知道的是,所有的注解的父接口都为java.lang.Annotation接口,所以只需要通过反射,在运行时动态地获取到Annotation接口,再将Annotation接口转换为具体的注解类,然后就可以通过注解类中自定义的成员变量(也就是成员方法)去获取到注解中的信息了。

1.AnnotationElement接口

AnnotationElement接口位于java.lang.reflect包下,实现它的类就表明可以通过反射获取到该类的注解信息,而实现了该接口的类有:

  • AccessibleObject
  • Class
  • Constructor
  • Executable
  • Field
  • Method
  • Package
  • Parameter

所以可以先使用反射获取到上述的类,然后通过这些就可以调用AnnotationElement接口规定的方法来获取和该类相关的代码了AnnotationElement接口有规定了以下几个常用的方法:

  • T getAnnotation(Class annotationClass)
    :获取该元素指定的注解,如果该注解不存在则返回null

  • Annotation[] getAnnotations():获取该元素所有的所有注解

  • default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) : 判断该元素上是否含有该注解。

  • Annotation[] getDeclaredAnnotations():返回直接存在于此元素上的所有注解。

  • T getDeclaredAnnotation(Class annotationClass):返回直接修饰该程序元素的指定类型的注解,不存在则返回 null。 (java8新增)

在这里插入图片描述

2.获取类上的注解并提取注解中的数据
/**
 * @Auther: ARong
 * @Description: 测试自定义注解
 */
@Deprecated
@DemoAnnotation(id = 6, name = "HelloWorld")
public class TestDemoAnnotation {

    /*
     * @Author ARong
     * @Description 获取类上的注解并提取数据
     * @Param
     * @return
     **/
    @Test
    public void testGetClassAnnotationMessage() {
        // 反射获取到类
        Class<TestDemoAnnotation> clazz = TestDemoAnnotation.class;
        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation.toString());
            if (annotation instanceof DemoAnnotation) {
                // 将Annotation转化为为DemoAnnotation并提取数据
                System.out.println(((DemoAnnotation) annotation).id());
                System.out.println(((DemoAnnotation) annotation).name());
            }
        }
    }
}

输出

@java.lang.Deprecated()
@thinking_in_java.annotation_learn.DemoAnnotation(id=6, name=HelloWorld)
6
HelloWorld

五.自定义注解

有一篇文章讲得很好,这里就不赘述了:
https://blog.youkuaiyun.com/lb850747906/article/details/52145346

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoringRong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值