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);
        }
    }
相关推荐
Sam_Deep_Thinking1 小时前
聊聊Java中的of
java·开发语言·架构
NE_STOP2 小时前
Docker--管理监控平台的应用
java
爱吃羊的老虎3 小时前
【JAVA】python转java:Spring Boot 入门
java·spring boot·python
Love_云宝儿3 小时前
GeoJSON简介
java·gis·地图·jts
摇滚侠4 小时前
JDBC 基础到高级一套通关!进阶篇 16-27
java
明志数科4 小时前
4D时序标注技术详解:让机器人理解连续动作的数据基础
java·算法·机器人
_qingche4 小时前
H2 数据库到 MySQL 数据迁移
java·数据库·spring boot·mysql·spring·重构·kotlin
小小de风呀4 小时前
de风——【从零开始学C++】(十一):list的基本使用和模拟实现
开发语言·c++·list
三行数学5 小时前
Matlab之父克利夫·莫勒尔逝世
开发语言·matlab