Java 代码阅读分析指南
预计阅读时间: 26 分钟
本文提供 5 个 Java 代码阅读的实战场景,每个场景包含具体步骤、Prompt 示例和预期输出。与 场景实战指南 的开发视角不同,本指南专注于代码理解与分析——如何高效地阅读、理解、分析已有的 Java 代码。
Info
代码阅读是开发者最高频的工作之一。研究表明,开发者在维护阶段花费在阅读代码上的时间远超编写新代码。使用 Claude Code + 语义工具组合,可以将代码阅读效率提升 3-5 倍。
为什么用 Claude Code 做代码阅读
传统的代码阅读依赖 IDE 的跳转和搜索功能,效率受限于:
- 跳转深度有限:IDE 的 "Go to Definition" 一次只能跳转一层,理解完整调用链需要反复跳转
- 上下文碎片化:每次跳转都会丢失之前的上下文,难以保持整体视图
- 缺乏全局分析:无法一次性看到多个文件之间的关系
- 文档缺失:遗留项目往往缺少注释和文档,需要从代码反推设计意图
Claude Code 的优势在于:
- 多文件并行阅读:一次读取多个文件,自动关联分析
- 语义级理解:结合 LSP 的类型信息,理解调用关系和依赖
- 交互式问答:可以随时追问细节,逐步深入理解
- 输出结构化:将代码理解转化为文档、图表和分析报告
场景一:理解业务逻辑(订单状态机)
本场景演示如何理解一个复杂的业务逻辑——订单状态机。通过阅读 Entity、Service 和 Controller 的代码,还原完整的状态转换规则和业务约束。
预计用时与工具分布
Step 1:定位状态管理的入口
这个项目的订单管理入口在哪里?有哪些 REST API 端点?
CodeGraph 的 codegraph_explore 快速找到订单相关的所有 API 端点。对 Spring Boot 项目,它能自动识别 @RestController 和 @RequestMapping,输出完整的路由图。
预期输出:
- 订单相关的所有 API 端点(创建、查询、更新状态等)
- 每个端点对应的 Controller 方法
- Controller → Service 的调用关系
Step 2:梳理状态枚举和转换规则
查看 OrderStatus 枚举和 OrderService 中所有修改状态的方法
Serena 的 get_symbols_overview 列出 OrderStatus 枚举的所有值,以及 OrderService 中涉及状态转换的方法签名。
> 查看 OrderStatus 枚举的所有值和 OrderService 中以 "update" 或 "transition" 开头的方法
预期输出:
- OrderStatus 的所有状态值(如 PENDING, PAID, SHIPPED, COMPLETED, CANCELLED)
- 每个状态转换方法的签名和参数
- 状态转换涉及的数据库操作
Step 3:还原完整状态机
基于 OrderService 的代码,画出订单状态机的完整转换图
Claude Code 阅读所有状态转换方法的实现,还原完整的状态机:
> 我需要理解订单的完整状态流转。请阅读 OrderService 中所有涉及状态转换的方法,
> 列出每种转换的:
> 1. 源状态和目标状态
> 2. 触发条件(什么操作会触发这个转换)
> 3. 前置校验(转换前检查了什么条件)
> 4. 副作用(转换后执行了什么操作,如发邮件、更新库存等)
> 5. 异常处理(校验失败时如何处理)
预期输出:
Step 4:分析异常场景和约束
订单状态转换中有哪些边界条件和异常场景?
通过阅读状态转换的校验逻辑,识别所有约束条件:
> 阅读 OrderService 中每个状态转换方法的 if 语句和抛出异常的地方,
> 列出所有业务约束:
> 1. 哪些状态转换是禁止的(如已发货不可取消)
> 2. 哪些转换有时限(如创建后 30 分钟内可取消)
> 3. 哪些转换需要外部依赖(如支付回调、物流状态)
> 4. 并发场景下如何保证一致性(乐观锁还是悲观锁)
场景一总结
场景二:追踪调用链(API 到数据库)
本场景演示如何追踪一个 API 请求从 Controller 到数据库的完整调用链。这是理解代码执行路径的基础技能,尤其在排查问题和性能优化时必不可少。
预计用时与工具分布
Step 1:从 API 入口开始追踪
GET /api/orders/{id} 的完整执行路径是什么?从 Controller 到数据库
CodeGraph 的 codegraph_trace 从 Controller 方法出发,逐层追踪到 Repository。
> 追踪 OrderController.getOrderById() 的完整调用链:
> Controller → Service → Repository → 数据库查询
> 列出每一层的方法调用和关键参数
预期输出:
OrderController.getOrderById(@PathVariable Long id)
└─ OrderService.getOrderById(Long id)
└─ OrderRepository.findById(Long id)
└─ JPA: SELECT * FROM orders WHERE id = ?
Step 2:理解 Service 层的业务逻辑
OrderService.getOrderById() 中做了什么处理?有缓存吗?
逐层深入 Service 方法的实现,理解业务逻辑:
> 详细阅读 OrderService.getOrderById() 方法:
> 1. 有缓存查询吗(@Cacheable 或 Redis 调用)?
> 2. 有额外的数据库查询吗(如查询关联的 OrderItem)?
> 3. 有业务校验吗(如检查订单归属)?
> 4. 返回值做了什么转换(Entity → DTO)?
预期输出:
OrderService.getOrderById(Long id)
├─ cache.get("order:" + id) // 缓存查询
├─ [缓存未命中] orderRepository.findById(id) // 数据库查询
├─ orderRepository.findItemsByOrderId(id) // 关联查询(潜在 N+1)
├─ orderMapper.toDTO(order, items) // Entity → DTO 转换
└─ cache.put("order:" + id, dto, 30min) // 写入缓存
Step 3:分析条件分支和异常路径
这个方法有哪些条件分支?异常在哪里抛出?
理解代码不仅要关注正常路径,还要分析所有分支和异常:
> 分析 OrderService.getOrderById() 的所有条件分支:
> 1. 缓存命中 vs 未命中的不同路径
> 2. 订单不存在时的处理(抛异常还是返回 null)
> 3. 订单状态对查询结果的影响
> 4. 并发场景下的竞态条件
Step 4:关联性能问题
这个调用链有哪些性能瓶颈?
结合 CodeGraph 的依赖分析和 ECC 的代码审查,识别性能问题:
> 分析 GET /api/orders/{id} 的性能:
> 1. 缓存命中率如何?缓存 key 的设计合理吗?
> 2. findItemsByOrderId 是否导致 N+1 查询?
> 3. Entity → DTO 转换是否有性能开销?
> 4. 数据库查询是否命中索引?
场景二总结
场景三:分析架构设计(分层与依赖)
本场景演示如何从代码层面理解项目的架构设计——分层策略、模块划分、依赖方向和设计模式。这是新成员快速理解项目全貌的关键步骤。
预计用时与工具分布
Step 1:获取项目整体视图
这个 Spring Boot 项目的整体架构是什么?有哪些模块和分层?
CodeGraph 的 codegraph_explore 一次性获取项目结构的完整视图。
> 分析这个项目的整体架构:
> 1. 是单模块还是多模块 Maven 项目?
> 2. 源代码的包结构是什么?
> 3. 有哪些技术栈(Spring Boot 版本、数据库、缓存等)?
> 4. 配置文件中有什么关键配置?
预期输出:
项目结构:
├── src/main/java/com/example/
│ ├── controller/ // REST API 层
│ ├── service/ // 业务逻辑层
│ ├── repository/ // 数据访问层
│ ├── entity/ // 数据库实体
│ ├── dto/ // 数据传输对象
│ ├── config/ // 配置类
│ └── exception/ // 异常定义
├── src/main/resources/
│ ├── application.yml
│ └── db/migration/ // Flyway 迁移脚本
└── src/test/
Step 2:分析分层策略和依赖方向
这个项目遵循什么样的分层模式?依赖方向是否合理?
通过 CodeGraph 的依赖分析,检查分层是否遵循依赖倒置原则:
> 分析项目的分层依赖:
> 1. Controller 层依赖了什么?是否直接依赖了 Repository?
> 2. Service 层是否依赖了其他 Service?有循环依赖吗?
> 3. Entity 层是否有业务逻辑(贫血模型 vs 充血模型)?
> 4. 是否有跨层调用(Controller 直接调用 Repository)?
预期输出:
Step 3:识别设计模式和架构决策
项目中使用了哪些设计模式?有哪些关键的架构决策?
阅读代码识别常见的设计模式:
> 在这个项目中识别设计模式:
> 1. 是否使用了 Strategy 模式(如不同的支付方式)?
> 2. 是否使用了 Observer 模式(如事件驱动)?
> 3. 是否使用了 Template Method(如通用的 CRUD 模板)?
> 4. 异常处理采用了什么策略(全局处理 vs 局部处理)?
> 5. 配置管理有什么特点(Profile、Config Server)?
Step 4:架构健康评估
这个项目的架构有哪些问题?如何改进?
结合 ECC 的代码审查和 CodeGraph 的依赖分析,评估架构健康度:
> 评估项目架构的健康度:
> 1. 依赖方向是否一致(有无反向依赖)?
> 2. 模块之间的耦合度如何?
> 3. 是否有上帝类(God Class,超过 300 行)?
> 4. 是否有循环依赖?
> 5. 测试覆盖率如何?是否有集成测试?
场景三总结
场景四:解读代码审查
本场景演示如何理解一段已经完成的代码审查(Code Review)——审查者提出了哪些意见、被审代码做了什么修改、最终的决策是什么。这是学习团队代码规范和提升代码质量理解的有效方式。
预计用时与工具分布
Step 1:理解 PR 的整体变更
这个 PR 做了什么修改?变更涉及哪些文件?
通过 git log 和 git diff 快速理解 PR 的整体变更:
> 分析最近的 PR(#123):
> 1. 这个 PR 的目标是什么?
> 2. 修改了哪些文件?每个文件改了什么?
> 3. 变更的规模有多大(行数、文件数)?
预期输出:
PR #123: 重构订单查询接口,支持分页和过滤
变更文件:5 个
- OrderController.java (+45, -12)
- OrderService.java (+89, -34)
- OrderRepository.java (+15, -3)
- OrderDTO.java (+23, -8)
- OrderControllerTest.java (+67, -21)
Step 2:分析审查意见
审查者提出了哪些意见?哪些被采纳了?
阅读 PR 中的审查评论,理解审查者的关注点:
> 阅读 PR #123 的所有审查评论,分类整理:
> 1. 哪些是代码风格问题(如命名、格式)?
> 2. 哪些是逻辑问题(如边界条件、异常处理)?
> 3. 哶些是架构问题(如分层、依赖方向)?
> 4. 哪些是性能问题(如 N+1 查询、缓存)?
> 5. 每条意见的最终状态(已修复 / 已讨论后保留 / 待处理)?
预期输出:
Step 3:还原最终决策
审查者和开发者最终达成了什么共识?
分析审查过程中的讨论,理解最终决策的理由:
> 阅读 PR #123 中的讨论线程,还原以下决策:
> 1. 为什么选择使用 @EntityGraph 而不是 JOIN FETCH?
> 2. 为什么保留了现有的异常处理策略而不是使用 ProblemDetail?
> 3. 分页参数的默认值是如何确定的?
Step 4:提炼代码规范和最佳实践
从这次代码审查中可以学到什么?
将审查意见转化为可复用的代码规范:
> 基于 PR #123 的审查意见,总结这个团队的代码规范:
> 1. 命名规范(方法名、变量名的约定)
> 2. 异常处理规范(何时抛异常、如何包装)
> 3. 测试规范(需要测试什么、如何命名测试)
> 4. 分层规范(Controller 和 Service 的职责边界)
场景四总结
场景五:遗留项目代码接管
本场景演示如何系统性地接管一个缺少文档的遗留 Java 项目。与 场景实战指南 中的遗留项目场景侧重开发不同,本场景专注于纯阅读和理解——在不修改任何代码的情况下,快速建立对项目的全面认知。
预计用时与工具分布
Step 1:快速建立全局视图
这个项目的整体架构是什么?有哪些技术栈和核心模块?
CodeGraph 的 codegraph_explore 快速获取项目的完整架构视图。对遗留项目,这一步回答最基础的问题:"这个项目是做什么的?"
> 分析这个 Spring Boot 项目的全局视图:
> 1. 项目的业务领域是什么(电商、金融、社交)?
> 2. 使用了什么技术栈(Spring Boot 版本、数据库、缓存、消息队列)?
> 3. 有哪些主要模块(用户、订单、支付、库存)?
> 4. 项目结构是否清晰(分层是否一致)?
预期输出:
- 项目技术栈清单
- 模块划分和依赖关系
- 数据库 Entity 和表结构
- API 端点列表
Step 2:梳理核心类和业务域
项目中最核心的类有哪些?它们的职责是什么?
使用 Serena 的 get_symbols_overview 快速列出核心类的结构:
> 查看以下核心类的符号概览:
> 1. UserService.java — 列出所有公开方法
> 2. OrderService.java — 列出所有公开方法
> 3. PaymentService.java — 列出所有公开方法
> 4. AuthService.java — 列出所有公开方法
> 5. 每个类的代码行数和方法数量
预期输出:
Step 3:分析依赖关系和潜在问题
项目中有哪些依赖关系?有没有循环依赖或过度耦合?
CodeGraph 的依赖分析帮助识别架构问题:
> 分析项目的依赖关系:
> 1. Service 之间有哪些依赖?是否有循环依赖?
> 2. 哪些类的代码行数超过 300 行(潜在的 God Class)?
> 3. 哪些方法的参数超过 5 个(参数过多)?
> 4. 项目中有哪些硬编码的配置值(数据库连接、API Key)?
Step 4:生成接管文档
为新接手的开发者生成一份项目接管指南
基于前面的分析,Claude Code 生成一份结构化的接管文档:
> 基于对项目的分析,生成一份《项目接管指南》,包含:
> 1. 项目概述(业务领域、技术栈、项目结构)
> 2. 核心模块说明(每个模块的职责和关键类)
> 3. 数据库设计(表结构和主要关系)
> 4. API 文档(主要端点和请求/响应格式)
> 5. 开发环境搭建(如何本地运行项目)
> 6. 常见问题和注意事项
> 7. 推荐的阅读顺序
Step 5:标记技术债务
项目中有哪些技术债务需要关注?
识别并标记技术债务,帮助优先级排序:
> 识别项目中的技术债务:
> 1. 缺少单元测试的模块
> 2. 缺少注释的关键方法
> 3. 过时的依赖版本
> 4. 重复代码(DRY 原则违反)
> 5. 硬编码的配置值
> 6. 缺少异常处理的代码
场景五总结
通用技巧
Prompt 优化技巧
- 明确范围:告诉 Claude Code 你要理解的具体模块或类,而不是"整个项目"
- 分层提问:先问全局视图,再逐层深入细节
- 要求输出格式:要求 Claude Code 输出表格、列表或图表,比纯文字更清晰
- 追问细节:对不理解的代码,直接要求解释具体的逻辑
常见 Prompt 模板
> 解释 [类名].[方法名] 的作用,包括:
> 1. 方法的输入参数是什么
> 2. 方法做了什么处理
> 3. 方法的返回值是什么
> 4. 方法可能抛出什么异常
> 追踪 [API 路由] 的完整调用链,从 Controller 到数据库
> 分析 [类名] 的依赖关系,哪些类依赖它,它依赖哪些类
> 这个项目的 [模块名] 模块是如何工作的?有哪些核心类?
工具选择建议
相关资源