Java注解、元注解、自定义注解定义及应用

1. 注解的定义与本质

注解(Annotation),在Java开发中,注解为我们提供了方法,可以在代码中添加信息,而这些信息可以被编译器、开发工具或运行时环境读取和处理,是主流框架不可或缺的组成部分。可以理解为代码的"标签"或"标记"。

  • 核心接口:java.lang.annotation.Annotaton
  • 使用位置:类或类成员上
  • 使用个数:一个或多个
  • 定义格式:public @interface 注解名{}

1.1 注解的作用

  1. 编译检查
  2. 代码生成 :用于生成辅助代码、配置文件等(如Lombok的@Data)等。
  3. 运行时处理 :在程序运行时,通过反射读取注解信息,动态改变程序行为(如Spring的@Autowired、JUnit的@Test)等。

1.2 内置注解示例

Java提供了一些内置注解,我们早已在不知不觉中使用了。

java 复制代码
// 重写父类方法
@Override
public String toString() {
    return "这是一个重写的方法";
}

2. 元注解(Meta-Annotation)

可以理解为是用来解释注解的注解;注解中以抽象方法的方式完成参数传递;传递的参数数据类型,根据抽象方法的返回值决定;如果没有默认值要求必须传值。

2.1 常用的元注解

① @Target 定义注解生效位置

应用:@Target(ElementType.METHOD)

枚举类ElementType 常见使用的作用范围
TYPE -- 类
FIELD -- 字段
CONSTRUCTOR -- 构造器
METHOD--方法

② @Retention 定义注解生效的时间

应用:@Retention(RetentionPolicy.SOURCE)

枚举类RetentionPolicy 常见使用的生效时间
SOURCE -- 源码时期
CLASS -- 字节码时期
RUNTIME -- 运行时期

③ @Documented 将注解编写到帮助文档中

④ @Inherited 当前注解可以被继承

3. 自定义注解

掌握了元注解,我们就可以定义自己的注解了。自定义注解使用@interface关键字,其本质是一个接口,继承java.lang.annotation.Annotation接口。自定义注解必须编写@Target、@Retention这两个注解。

应用:定义自定义注解,并在Student类中使用,实现获取到自定义注解中的值

3.1 定义自定义注解

java 复制代码
/**
 * 自定义注解必须写上@Target  @Retention
 */
 //定义注解作用范围为方法和构造器
@Target({ElementType.METHOD,ElementType.CONSTRUCTOR})
//定义注解生效为运行时期
@Retention(RetentionPolicy.RUNTIME)
public @interface DIYAnnotation {
    /*
        想要传递几个参数,就定义几个抽象方法
        如果注解中只有一个抽象方法,方法名一般都是value
     */
    String[] value();//没有默认值,必须传值

    boolean flag() default true;//有默认可以省略不传参
}

3.2 使用自定义注解

java 复制代码
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Student {

    private String name;
    private int age;
    private String sex;

    //如果值传递一个参数,且是value是可以省略不写的,如果多个参数,必须标注参数名=值
    @DIYAnnotation(value= "aa",flag = false)
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

3.3 应用自定义注解

java 复制代码
    @Test
    public void getParamFromAnnotation() throws Exception {
        //获取字节码对象
        Class<Student> clazz = Student.class;
        //通过字节码对象获取构造器对象;构造器是指定类的,下面获取的构造器对象,会根据类去联想生成接收变量
        Constructor<Student> constructor = clazz.getConstructor(String.class, int.class);
        //API:isAnnotationPresent():判断构造器上是否使用了指定的注解
        if (constructor.isAnnotationPresent(DIYAnnotation.class)){
            //通过构造器对象,获取注解对象
            DIYAnnotation annotation = constructor.getAnnotation(DIYAnnotation.class);
            String[] values = annotation.value();
            System.out.println(Arrays.toString(values));
            boolean flag = annotation.flag();
            System.out.println(flag);
        }
    }
相关推荐
qfljg4 小时前
OpenRewrite 实战指南
java
Sylvia33.4 小时前
LOL实时数据接入深度解析:从WebSocket到完整数据模型
java·网络·python·websocket·网络协议
2601_962071579 小时前
【Java报错已解决】org.springframework.beans.factory.BeanCreationException
java·开发语言
zww894911110 小时前
酒馆预约系统开发实战:从需求分析到上线全流程指南
java·eclipse
淡海水10 小时前
07-04-并发-ConcurrentBag-T-工作窃取WorkStealing算法
开发语言·算法·c#·bag·concurrent·workstealing
CS_Zero11 小时前
C语言sizeof是函数吗?
c语言·开发语言
-今昭-12 小时前
《V2V 迁移实战:将 VMware 虚拟机转为 OpenStack 可用 Glance qcow2 镜像》
开发语言·python
zww894911113 小时前
匿名树洞系统开发实战:从需求分析到部署指南
java·eclipse
黑马程序员毕设14 小时前
基于Java的医院药品管理系统的优化设计与实现
java·开发语言·spring boot·小程序·架构·课程设计·毕设
木井巳14 小时前
【BFS/DFS 解决 FloodFill 算法】太平洋大西洋水流问题
java·算法·leetcode·深度优先·广度优先·宽度优先·推荐算法