@Target + @Retention + isAnnotationPresent + getAnnotation

先把 4 个东西一句话讲清

  1. @Target → 规定注解能贴在哪(类 / 方法 / 变量)
  2. @Retention → 规定注解运行时还活着(必须写)
  3. isAnnotationPresent → 检查有没有贴这个注解(返回 true/false)
  4. getAnnotation → 拿到注解本身,读取里面的值

一、前言:到底什么是注解?

一句话总结:注解就是贴在类、方法、变量上的「特殊标签」。

  • 单纯贴上标签:毫无作用
  • 通过反射扫描读取标签:注解才会产生对应的功能

我们日常使用的 @Override、@SuppressWarnings、Spring的@Controller,本质全部都是注解。

二、四大核心知识点(必学)

自定义注解离不开4个核心部分,我帮你用最简单的语言拆分:

1. @Target(元注解)------ 管控注解【贴在哪里】

作用:给自定义注解制定规则,限制这个标签能粘贴的位置,禁止乱贴。

常用取值(小白只需要背这5个):

  • ElementType.TYPE:可以贴在类、接口、枚举上
  • ElementType.FIELD:可以贴在成员变量上
  • ElementType.METHOD:可以贴在成员方法上
  • ElementType.CONSTRUCTOR:可以贴在构造方法上
  • ElementType.PARAMETER:可以贴在方法参数上

补充:不添加@Target,注解默认可以贴在任意位置。

2. @Retention(元注解)------ 管控注解【活多久】

作用 :控制注解的生命周期,自定义注解想要被反射读取,必须配置它。

三种生命周期:

  • SOURCE:源码阶段有效,编译后直接丢失(如@Override)
  • CLASS:编译阶段有效,运行阶段丢失(默认值)
  • RUNTIME :运行阶段一直存在,唯一能被反射读取(自定义注解必选)

💡 小白铁律:只要是需要自己写、需要读取的自定义注解,无脑写 @Retention(RetentionPolicy.RUNTIME)

3. isAnnotationPresent() ------ 判断【有没有贴标签】

作用:通过反射,判断某个类/方法/变量上是否标注了指定注解。

返回值:布尔类型

  • true:已添加该注解
  • false:未添加该注解

4. getAnnotation() ------ 读取【标签内部数据】

作用:如果已经判断存在注解,通过该方法获取注解对象,进而读取注解内部存储的参数值。

三、完整实战案例(全程可直接运行)

步骤1:自定义注解

定义注解,限制仅能贴在类上,设置运行时永久存活,并自定义两个属性存储数据。

java 复制代码
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// 规定:该注解只能贴在 类/接口 上
@Target(ElementType.TYPE)
// 规定:运行时存活,支持反射读取
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
    // 自定义注解参数
    String name();
    int age();
}

步骤2:使用注解

在实体类上添加注解,并给注解内部参数赋值。

kotlin 复制代码
// 给User类打上标签,并传入数据
@MyAnno(name = "掘金小白", age = 18)
public class User {
    private String username;
    private String password;
}

步骤3:反射读取注解(核心)

先判断是否存在注解,再获取注解对象、读取内部数据。

arduino 复制代码
public class AnnotationTest {
    public static void main(String[] args) {
        // 1. 获取类的Class对象
        Class<User> clazz = User.class;

        // 2. 判断类上是否存在@MyAnno注解
        boolean isExist = clazz.isAnnotationPresent(MyAnno.class);
        System.out.println("是否添加注解:" + (isExist ? "是" : "否"));

        // 3. 存在注解则读取内部数据
        if(isExist){
            // 获取注解对象
            MyAnno anno = clazz.getAnnotation(MyAnno.class);
            // 读取注解参数
            String name = anno.name();
            int age = anno.age();
            System.out.println("注解存储姓名:" + name);
            System.out.println("注解存储年龄:" + age);
        }
    }
}

步骤4:运行结果

复制代码
是否添加注解:是
注解存储姓名:掘金小白
注解存储年龄:18

四、拓展:注解贴在方法上(补充案例)

修改注解@Target,支持粘贴在方法上,实现方法级别的注解读取。

less 复制代码
// 可贴在类 和 方法上
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
    String name();
    int age();
}

使用+读取:

csharp 复制代码
public class User {
    @MyAnno(name = "测试方法", age = 20)
    public void login(){
        System.out.println("用户登录");
    }
}
ini 复制代码
import java.lang.reflect.Method;

public class AnnotationTest {
    public static void main(String[] args) throws Exception {
        Class<User> clazz = User.class;
        // 获取指定方法
        Method loginMethod = clazz.getMethod("login");

        if(loginMethod.isAnnotationPresent(MyAnno.class)){
            MyAnno anno = loginMethod.getAnnotation(MyAnno.class);
            System.out.println(anno.name());
        }
    }
}

五、终极总结(背诵版)

  1. @Target:约束注解的使用位置,防止注解乱贴
  2. @Retention :设置注解生命周期,自定义注解必须配置 RUNTIME 才能被反射读取
  3. isAnnotationPresent() :做判断,查询目标位置是否存在指定注解
  4. getAnnotation() :获取注解对象,读取注解内部存储的参数

六、极简口诀

Target定位置,Retention保性命; 先判是否存在,再拿注解取值!

相关推荐
行百里er13 小时前
Redis 完结篇——Redis 热点问题在 Spring Boot 项目中实战
redis·后端
高频因子挖掘机14 小时前
只取最近 60 个交易日,却每次拉全历史:量化脚本变慢的原因与改法
后端·github·api
孟健15 小时前
从5000亿Token到83%字节匹配:AI逆向工程与重构的工程闭环实践
后端·架构·ai编程
码事漫谈16 小时前
丢得静悄悄,谈一谈 Agent 的记忆是怎么没的
后端
迪飞特科技16 小时前
智慧物业平台实战:Spring Boot 整合小程序实现报修巡检费用全流程
spring boot·后端·小程序
考虑考虑16 小时前
@JsonInclude注解使用
spring boot·后端·spring
IT_陈寒16 小时前
Vite的这个问题坑了我三天,原来如此解决!
前端·人工智能·后端
网易云信16 小时前
大模型能上岗做销售吗?我们让 12 款国产模型交了 420 份作业
前端·后端
CCblandy17 小时前
HTTP 长连接 3 类故障实测:[WinError 10053]、99 个 TIME_WAIT、69 次多余握手,4 种对策怎么选
后端·python·网络协议·http·云原生·性能优化·架构
蜗牛互联网17 小时前
Python Agent工具调用的白名单、参数校验与审批门禁
java·服务器·前端·人工智能·后端·python