You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RetentionPolicy.SOURCE注解未写入字节码,如何在运行时访问?

关于RetentionPolicy.SOURCE注解运行时访问的问题

嘿,我来给你掰扯清楚这个事儿哈!首先得明确一个核心点:RetentionPolicy.SOURCE类型的注解,确实会在编译完成后被丢弃,不会被写入字节码——但这并不意味着你完全没法访问注解里的东西,得看你要访问的是什么。

先搞懂:你例子里的MyAnno.a到底是什么?

你定义的MyAnno是个注解,但里面的int a = 4;可不是注解的属性哦!在Java里,注解本质是一种特殊的接口,而在接口里定义的变量默认就是**public static final的静态常量**。哪怕这个注解是SOURCE级别的,MyAnno这个注解类本身还是会被编译成.class文件的——SOURCE策略只丢弃的是注解的使用实例(比如你给某个方法加@MyAnno(val=xxx)),而注解类本身不会被丢。

所以你例子里的MyAnno.a,其实就是普通的接口静态常量,和注解的保留策略压根没关系,运行时直接通过类名访问完全没问题。

补全代码验证一下

把你的代码补全后,运行起来完全正常:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.SOURCE)
@interface MyAnno {
    int a = 4; // 静态常量,属于MyAnno接口的成员
    int val(); // 这才是注解的属性,只有注解实例被保留时才能获取
}

public class Example {
    public static void test() {
        System.out.println("MyAnno.a = " + MyAnno.a);
    }

    public static void main(String[] args) {
        test();
    }
}

编译运行后,控制台会输出:MyAnno.a = 4,完美运行。

关键区别:注解属性 vs 静态成员

这里一定要分清两个东西:

  • 注解属性(比如val()):只有当注解的保留策略是CLASS或RUNTIME时,你才能通过反射获取到某个类/方法上的注解实例,进而拿到val的值。如果是SOURCE级别的,编译后注解实例就没了,根本拿不到。
  • 注解类的静态常量(比如a):这是注解类(接口)本身的成员,只要注解类被编译成.class文件,运行时就能直接访问,和注解的保留策略无关。

所以结论就是:你例子里的代码本身就可以直接运行访问MyAnno.a,不需要额外操作——因为它是静态常量,和注解的Retention策略没关系~

内容的提问来源于stack exchange,提问作者1 JustOnly 1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:38:03