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);
        }
    }
相关推荐
2301_32241428043 小时前
基于SpringBoot+Vue的休闲零食超市管理系统的设计与实现59004-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·vue.js·spring boot·redis·mysql·决策树·推荐算法
懂点Tech4 小时前
ctfshow MISC入门图片篇(信息附加):misc41解题思路
开发语言·python
金銀銅鐵5 小时前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(上)
java·后端·ai编程
catchadmin5 小时前
PHP 8.7 协程新提案 让跨协程代码共享请求身份
开发语言·php
福建佰胜张工6 小时前
SMC 薄型气爪 MHF2-16D1 深度解析:平行开闭、低剖面结构在自动化装配中的选型与落地
java·服务器·安全·自动化
念何架构之路6 小时前
go-grpc设计思想
开发语言·后端·golang
catoop6 小时前
API Key 设计与安全生成方案:结构拆解、数据库设计与 Java 实现
java·数据库·安全
system_error_x6 小时前
SpringBoot 集成 Thymeleaf 简洁入门
java·spring boot·后端
酷炫码神7 小时前
Day 10|Pinia 状态管理:把散落在各组件的数据,收进一个全局仓库
android·开发语言·javascript
驭渊的小故事7 小时前
Spring AI Alibaba 实战:从maven依赖治理到声明式工具调用
java·人工智能·spring