0

0

Java中的反射:操作注解并获取注解属性值的标准方法

P粉602998670

P粉602998670

发布时间:2026-02-11 14:14:02

|

798人浏览过

|

来源于php中文网

原创

反射获取注解实例须用getDeclaredAnnotation()而非isAnnotationPresent(),注意默认值非null、重复注解需用getDeclaredAnnotationsByType(),且注解值仅为编译期字面量。

java中的反射:操作注解并获取注解属性值的标准方法

获取类/方法/字段上的注解实例

反射中拿到注解,核心是调用 getAnnotation()getDeclaredAnnotation()。前者会沿继承链向上查找(包括接口、父类),后者只查当前声明处——多数时候你该用后者,避免误取到父类的同名注解。

常见错误:用 isAnnotationPresent() 判断存在后,直接强转返回值,结果抛 ClassCastException。它返回的是 boolean,不是注解对象。

  • 必须用 getDeclaredAnnotation(YourAnno.class) 获取实际注解实例
  • 注解类型必须在编译期可见(即不能是 @Retention(RetentionPolicy.SOURCE)
  • 如果注解本身带 @Inherited,且目标类继承自带该注解的父类,getAnnotation() 才可能返回非空

读取注解的属性值(尤其是默认值和数组)

注解属性本质是接口方法,通过反射调用其 getter 即可。但要注意:没有显式赋值的属性,会返回编译期设定的 default 值,而不是 null(除非 default 就是 null)。

数组属性容易踩坑:不能直接用 annotation.values()Object[],而要用对应类型的数组方法,比如 String[] names = anno.value();

立即学习Java免费学习笔记(深入)”;

Flowith
Flowith

一款GPT4驱动的节点式 AI 创作工具

下载
  • 基本类型和 String 属性:直接调用方法名,如 anno.name()
  • 数组属性:必须用显式类型接收,如 Class>[] groups = anno.groups();,否则编译失败或运行时报 ClassCastException
  • 枚举/Class 类型属性:返回的就是对应枚举常量或 Class 对象,无需额外处理

处理重复注解(@Repeatable)

Java 8 引入 @Repeatable 后,同一位置可声明多个同类型注解,但反射 API 不会自动聚合——getDeclaredAnnotation() 只返回第一个,其余被忽略。

正确做法是改用 getDeclaredAnnotationsByType(),它返回 Annotation[],包含所有匹配的重复注解实例。

  • 旧写法 clazz.getAnnotation(MyAnno.class) 在重复场景下必然漏数据
  • 必须用 clazz.getDeclaredAnnotationsByType(MyAnno.class)(注意是 ByType,不是 ByClass
  • 如果注解没加 @RepeatableByType 和普通 getDeclaredAnnotation 行为一致,安全降级

注解属性值是动态表达式?别指望反射能解析

反射只能读取编译后固化在 class 文件里的字面值。像 Spring 的 @Value("${port}") 或 Lombok 的 @Getter(lazy = true),里面的字符串或布尔值是原始字面量,不是运行时计算结果。

比如 @RequestMapping("/api/v${version}"),反射拿到的 value() 就是字符串 "/api/v${version}",不会替换成真实版本号。

  • 所有占位符、SpEL 表达式、条件逻辑,都是框架在反射之后自行解析的
  • 想模拟框架行为?得自己实现表达式引擎,反射不负责这事
  • 测试时若依赖注解值做分支判断,务必确认你读到的是原始字符串,而非期望中的“渲染后结果”
注解反射看似简单,但默认值语义、重复注解入口、表达式惰性求值这三点,最容易在上线后突然暴露——尤其当别人在注解里写了 ${} 却以为你能自动展开。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

120

2025.08.06

Java Spring Security 与认证授权
Java Spring Security 与认证授权

本专题系统讲解 Java Spring Security 框架在认证与授权中的应用,涵盖用户身份验证、权限控制、JWT与OAuth2实现、跨站请求伪造(CSRF)防护、会话管理与安全漏洞防范。通过实际项目案例,帮助学习者掌握如何 使用 Spring Security 实现高安全性认证与授权机制,提升 Web 应用的安全性与用户数据保护。

77

2026.01.26

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

688

2023.08.02

java中boolean的用法
java中boolean的用法

在Java中,boolean是一种基本数据类型,它只有两个可能的值:true和false。boolean类型经常用于条件测试,比如进行比较或者检查某个条件是否满足。想了解更多java中boolean的相关内容,可以阅读本专题下面的文章。

356

2023.11.13

java boolean类型
java boolean类型

本专题整合了java中boolean类型相关教程,阅读专题下面的文章了解更多详细内容。

36

2025.11.30

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

243

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

665

2024.03.01

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1547

2023.10.24

Rust异步编程与Tokio运行时实战
Rust异步编程与Tokio运行时实战

本专题聚焦 Rust 语言的异步编程模型,深入讲解 async/await 机制与 Tokio 运行时的核心原理。内容包括异步任务调度、Future 执行模型、并发安全、网络 IO 编程以及高并发场景下的性能优化。通过实战示例,帮助开发者使用 Rust 构建高性能、低延迟的后端服务与网络应用。

1

2026.02.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3.4万人学习

C# 教程
C# 教程

共94课时 | 9.1万人学习

Java 教程
Java 教程

共578课时 | 62.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号