Java原生@Deprecated不支持自定义属性和反射读取提示文字,需自定义@DeprecatedSince注解(含value/version字段)、通过反射扫描提取说明,并兼容原生@Deprecated以增强审计能力。

Java 原生的 @Deprecated 是一个内置注解(`java.lang.Deprecated`),它**不支持自定义属性**,也不能被反射直接“读取提示文字”。你无法通过反射获取类似 @Deprecated("请改用 newMethod()") 这样的字符串值——因为标准 @Deprecated 的定义中根本没有 value 字段。
所以,要实现“动态代码审计”中识别带说明的弃用方法,你需要的是:一个自定义的、可携带描述信息的弃用注解,再配合反射读取它。以下是具体做法:
1. 定义可携带说明的自定义弃用注解
创建一个保留策略为 RUNTIME 的注解,允许通过反射访问,并添加 value() 或 reason() 字段存储提示文本:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DeprecatedSince {
String value() default "该方法已弃用,请检查替代方案";
String version() default "";
}
这样就能在方法上使用:
@DeprecatedSince("请改用 calculateV2(),精度更高")
public double calculate() { ... }
2. 用反射扫描类中的废弃方法并提取提示
遍历目标类的所有 Method,检查是否标注了你的自定义注解,并读取其字段:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 调用
method.getAnnotation(DeprecatedSince.class) - 若返回非 null,说明该方法被标记为弃用
- 调用
annotation.value()或annotation.reason()获取提示文本 - 可结合
method.getDeclaringClass()和method.getName()构建完整签名用于审计报告
3. 集成到审计流程(例如启动时扫描或测试阶段)
常见实用方式包括:
- 在 Spring Boot 启动时,用
ClassPathScanningCandidateComponentProvider扫描特定包下所有@Component类,再反射检查其 public 方法 - 编写 JUnit 测试,对指定模块的 API 类批量校验:发现带
@DeprecatedSince但未加@Test或未被日志/监控覆盖的方法,自动失败 - 与 IDE 插件或 SonarQube 自定义规则联动:将注解信息导出为 JSON 报告供静态分析消费
4. 补充建议:兼容原生 @Deprecated 并增强语义
如果你仍需兼容 JDK 自带的 @Deprecated(比如第三方库方法),可以同时检查:
-
method.isAnnotationPresent(Deprecated.class)→ 表示基础弃用标记 - 再叠加检查你的
@DeprecatedSince→ 提供可读原因 - 两者共存时,优先采用自定义注解的
value(),作为审计报告中的“弃用说明”
这样既不破坏现有约定,又提升了可维护性与自动化审计能力。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










