java-best-practices-code-review
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWorks with .java files, Spring components, and Java projects of any size.
适用于.java文件、Spring组件及任意规模的Java项目。
Java Code Review
Java代码审查
Table of Contents
目录
Purpose
目的
Performs comprehensive code reviews of Java code against industry best practices, SOLID principles, and modern Java idioms. Provides actionable feedback to improve code quality, maintainability, and security.
针对行业最佳实践、SOLID原则及现代Java惯用写法,对Java代码进行全面审查。提供可落地的反馈,以提升代码质量、可维护性和安全性。
When to Use
适用场景
Use this skill when you need to:
- Review Java files for code quality issues
- Analyze SOLID principle compliance
- Evaluate exception handling patterns
- Assess thread safety in concurrent code
- Audit resource management (try-with-resources usage)
- Check naming conventions and coding standards
- Review Stream API and Optional usage
- Verify modern Java features adoption (Java 8+ idioms)
- Conduct PR reviews for Java projects
- Identify refactoring opportunities
在以下场景中使用本技能:
- 审查Java文件中的代码质量问题
- 分析是否符合SOLID原则
- 评估异常处理模式
- 评估并发代码的线程安全性
- 审计资源管理(try-with-resources的使用情况)
- 检查命名规范和编码标准
- 审查Stream API和Optional的使用
- 验证是否采用了现代Java特性(Java 8+惯用写法)
- 对Java项目进行PR审查
- 识别重构机会
Quick Start
快速开始
Point to any Java file or directory and receive immediate feedback on code quality issues:
bash
undefined指向任意Java文件或目录,即可立即获取代码质量问题的反馈:
bash
undefinedReview a single file
审查单个文件
Review src/main/java/com/example/UserService.java
Review src/main/java/com/example/UserService.java
Review all Java files in a package
审查某个包下的所有Java文件
Review all Java files in src/main/java/com/example/service/
undefinedReview all Java files in src/main/java/com/example/service/
undefinedInstructions
操作步骤
Step 1: Identify Target Scope
步骤1:确定目标范围
Determine what needs to be reviewed:
- Single Java class file
- Package directory (all .java files)
- Specific component type (controllers, services, repositories)
- Entire src tree
Use Glob to find Java files if not explicitly specified:
bash
**/*.java # All Java files
src/main/java/**/*Service.java # All service classes明确需要审查的内容:
- 单个Java类文件
- 包目录(所有.java文件)
- 特定组件类型(控制器、服务、仓库)
- 整个src目录树
如果未明确指定,使用Glob匹配Java文件:
bash
**/*.java # 所有Java文件
src/main/java/**/*Service.java # 所有服务类Step 2: Read and Analyze Code
步骤2:读取并分析代码
For each Java file, perform multi-dimensional analysis:
SOLID Principles Assessment:
- Single Responsibility: Does class have one clear purpose?
- Open/Closed: Is class extensible without modification?
- Liskov Substitution: Are inheritance hierarchies sound?
- Interface Segregation: Are interfaces focused and minimal?
- Dependency Inversion: Does code depend on abstractions?
Code Quality Checks:
- Naming conventions (camelCase, PascalCase, UPPER_SNAKE_CASE)
- Method length (flag methods over 50 lines)
- Class cohesion (related methods grouped together)
- Magic numbers and strings (should be constants)
- Code duplication (DRY principle violations)
Exception Handling:
- Proper exception types (checked vs unchecked)
- No empty catch blocks
- No catching generic Exception unless necessary
- Meaningful error messages
- Proper exception chaining (throw new CustomException(e))
Resource Management:
- try-with-resources for AutoCloseable resources
- Proper Stream/File/Connection closing
- No resource leaks
Modern Java Patterns:
- Stream API usage (prefer streams over loops where appropriate)
- Optional instead of null returns
- Records for data classes (Java 14+)
- Switch expressions (Java 14+)
- Text blocks for multi-line strings (Java 15+)
Thread Safety:
- Proper synchronization if needed
- Immutability where possible
- Thread-safe collection usage
- Avoid shared mutable state
Security Concerns:
- No hardcoded credentials
- Proper input validation
- SQL injection prevention (use PreparedStatement)
- Path traversal vulnerabilities
- Sensitive data logging
对每个Java文件进行多维度分析:
SOLID原则评估:
- 单一职责:类是否有明确的单一用途?
- 开闭原则:类是否可扩展且无需修改原有代码?
- 里氏替换:继承体系是否合理?
- 接口隔离:接口是否聚焦且精简?
- 依赖倒置:代码是否依赖抽象而非具体实现?
代码质量检查:
- 命名规范(camelCase、PascalCase、UPPER_SNAKE_CASE)
- 方法长度(标记超过50行的方法)
- 类的内聚性(相关方法是否分组合理)
- 魔法值和魔法字符串(应定义为常量)
- 代码重复(违反DRY原则)
异常处理:
- 使用合适的异常类型(受检vs非受检)
- 无空catch块
- 除非必要,否则不要捕获通用Exception
- 有意义的错误信息
- 正确的异常链(throw new CustomException(e))
资源管理:
- 对AutoCloseable资源使用try-with-resources
- 正确关闭Stream/File/Connection
- 无资源泄漏
现代Java模式:
- Stream API的使用(合适场景下优先使用流而非循环)
- 使用Optional替代null返回值
- 记录类(Records)用于数据类(Java 14+)
- Switch表达式(Java 14+)
- 文本块用于多行字符串(Java 15+)
线程安全:
- 必要时使用正确的同步机制
- 尽可能使用不可变对象
- 使用线程安全的集合
- 避免共享可变状态
安全问题:
- 无硬编码凭证
- 正确的输入验证
- 防止SQL注入(使用PreparedStatement)
- 路径遍历漏洞
- 敏感数据日志
Step 3: Generate Structured Review Report
步骤3:生成结构化审查报告
Organize findings by severity:
CRITICAL - Must fix immediately:
- Security vulnerabilities
- Resource leaks
- Thread safety violations in concurrent code
HIGH - Should fix soon:
- SOLID principle violations
- Poor error handling
- Significant code smells
MEDIUM - Improve when possible:
- Code duplication
- Naming convention issues
- Missing modern Java features
LOW - Nice to have:
- Code style inconsistencies
- Minor optimizations
- Documentation improvements
按严重程度整理发现的问题:
CRITICAL(严重)- 必须立即修复:
- 安全漏洞
- 资源泄漏
- 并发代码中的线程安全违规
HIGH(高优先级)- 应尽快修复:
- SOLID原则违规
- 不良的错误处理
- 严重的代码异味
MEDIUM(中优先级)- 尽可能改进:
- 代码重复
- 命名规范问题
- 未使用现代Java特性
LOW(低优先级)- 锦上添花:
- 代码风格不一致
- 次要优化
- 文档改进
Step 4: Provide Actionable Recommendations
步骤4:提供可落地的建议
For each issue identified:
- Specify exact location (file, line number)
- Explain the problem clearly
- Show code example of the issue
- Provide corrected code example
- Explain why the change improves code quality
针对每个发现的问题:
- 指定确切位置(文件、行号)
- 清晰解释问题
- 展示问题代码示例
- 提供修正后的代码示例
- 解释修改为何能提升代码质量
Examples
示例
Example 1: Review Single Service Class
示例1:审查单个服务类
Input:
java
public class UserService {
private UserRepository userRepository = new UserRepository();
public User getUser(String id) {
User user = userRepository.findById(id);
if (user == null) {
return null;
}
return user;
}
}Review Output:
CRITICAL Issues:
- Line 2: Dependency Inversion violation - direct instantiation of UserRepository
Fix: Inject UserRepository via constructor
HIGH Issues:
- Line 7: Returns null instead of Optional<User>
Fix: Return Optional.ofNullable(user)
MEDIUM Issues:
- Class lacks @Service annotation (assuming Spring)
- No logging for diagnostic purposes
Recommended Refactoring:
```java
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private static final Logger log = LoggerFactory.getLogger(UserService.class);
public Optional<User> getUser(String id) {
log.debug("Fetching user with id: {}", id);
return Optional.ofNullable(userRepository.findById(id));
}
}undefined输入:
java
public class UserService {
private UserRepository userRepository = new UserRepository();
public User getUser(String id) {
User user = userRepository.findById(id);
if (user == null) {
return null;
}
return user;
}
}审查输出:
CRITICAL Issues:
- Line 2: Dependency Inversion violation - direct instantiation of UserRepository
Fix: Inject UserRepository via constructor
HIGH Issues:
- Line 7: Returns null instead of Optional<User>
Fix: Return Optional.ofNullable(user)
MEDIUM Issues:
- Class lacks @Service annotation (assuming Spring)
- No logging for diagnostic purposes
Recommended Refactoring:
```java
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private static final Logger log = LoggerFactory.getLogger(UserService.class);
public Optional<User> getUser(String id) {
log.debug("Fetching user with id: {}", id);
return Optional.ofNullable(userRepository.findById(id));
}
}undefinedExample 2: Review Controller with Multiple Issues
示例2:审查存在多个问题的控制器
Input:
java
public class UserController {
@GetMapping("/users/{id}")
public User getUser(@PathVariable String id) {
try {
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/db", "root", "password");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users WHERE id = " + id);
if (rs.next()) {
return new User(rs.getString("name"), rs.getString("email"));
}
} catch (Exception e) {
// ignore
}
return null;
}
}Review Output:
CRITICAL Issues:
1. Line 7: SQL Injection vulnerability - concatenating user input into query
Fix: Use PreparedStatement with parameters
2. Line 5: Hardcoded database credentials in code
Fix: Externalize to application.properties and use Spring's DataSource
3. Lines 5-10: Resource leak - Connection, Statement, ResultSet not closed
Fix: Use try-with-resources or Spring JdbcTemplate
4. Line 11-13: Empty catch block silently swallows exceptions
Fix: Log exception and throw appropriate response exception
HIGH Issues:
5. Architecture violation: Controller directly accessing database
Fix: Use Service layer and Repository pattern
6. Line 14: Returns null instead of proper HTTP 404
Fix: Throw ResponseStatusException or return ResponseEntity
MEDIUM Issues:
7. Missing @RestController annotation
8. No input validation on id parameter
9. No API documentation (@Operation, @ApiResponse)
Recommended Architecture:
```java
@RestController
@RequiredArgsConstructor
@Validated
public class UserController {
private final UserService userService;
@GetMapping("/users/{id}")
@Operation(summary = "Get user by ID")
public ResponseEntity<User> getUser(
@PathVariable @NotBlank String id) {
return userService.getUser(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
}
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
public Optional<User> getUser(String id) {
return userRepository.findById(id);
}
}
@Repository
public interface UserRepository extends JpaRepository<User, String> {
}undefined输入:
java
public class UserController {
@GetMapping("/users/{id}")
public User getUser(@PathVariable String id) {
try {
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/db", "root", "password");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users WHERE id = " + id);
if (rs.next()) {
return new User(rs.getString("name"), rs.getString("email"));
}
} catch (Exception e) {
// ignore
}
return null;
}
}审查输出:
CRITICAL Issues:
1. Line 7: SQL Injection vulnerability - concatenating user input into query
Fix: Use PreparedStatement with parameters
2. Line 5: Hardcoded database credentials in code
Fix: Externalize to application.properties and use Spring's DataSource
3. Lines 5-10: Resource leak - Connection, Statement, ResultSet not closed
Fix: Use try-with-resources or Spring JdbcTemplate
4. Line 11-13: Empty catch block silently swallows exceptions
Fix: Log exception and throw appropriate response exception
HIGH Issues:
5. Architecture violation: Controller directly accessing database
Fix: Use Service layer and Repository pattern
6. Line 14: Returns null instead of proper HTTP 404
Fix: Throw ResponseStatusException or return ResponseEntity
MEDIUM Issues:
7. Missing @RestController annotation
8. No input validation on id parameter
9. No API documentation (@Operation, @ApiResponse)
Recommended Architecture:
```java
@RestController
@RequiredArgsConstructor
@Validated
public class UserController {
private final UserService userService;
@GetMapping("/users/{id}")
@Operation(summary = "Get user by ID")
public ResponseEntity<User> getUser(
@PathVariable @NotBlank String id) {
return userService.getUser(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
}
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
public Optional<User> getUser(String id) {
return userRepository.findById(id);
}
}
@Repository
public interface UserRepository extends JpaRepository<User, String> {
}undefinedExample 3: Review Stream API Usage
示例3:审查Stream API使用
Input:
java
List<String> activeUserNames = new ArrayList<>();
for (User user : users) {
if (user.isActive()) {
activeUserNames.add(user.getName());
}
}
Collections.sort(activeUserNames);Review Output:
MEDIUM Issues:
- Lines 1-6: Imperative loop should use Stream API for clarity
- Line 7: Mutating list instead of using sorted stream
Recommended Refactoring:
```java
List<String> activeUserNames = users.stream()
.filter(User::isActive)
.map(User::getName)
.sorted()
.toList();Benefits:
- More declarative and readable
- Immutable result (.toList() returns unmodifiable list)
- Potential for parallel processing if needed
- Method reference usage (User::isActive)
undefined输入:
java
List<String> activeUserNames = new ArrayList<>();
for (User user : users) {
if (user.isActive()) {
activeUserNames.add(user.getName());
}
}
Collections.sort(activeUserNames);审查输出:
MEDIUM Issues:
- Lines 1-6: Imperative loop should use Stream API for clarity
- Line 7: Mutating list instead of using sorted stream
Recommended Refactoring:
```java
List<String> activeUserNames = users.stream()
.filter(User::isActive)
.map(User::getName)
.sorted()
.toList();Benefits:
- More declarative and readable
- Immutable result (.toList() returns unmodifiable list)
- Potential for parallel processing if needed
- Method reference usage (User::isActive)
undefinedRequirements
要求
- Java 8+ knowledge for Stream API, Optional, lambda expressions
- Java 11+ awareness for var, String methods, Collection.toArray()
- Java 14+ familiarity with records, switch expressions, text blocks
- Java 17+ understanding of sealed classes, pattern matching
- Understanding of SOLID principles and design patterns
- Familiarity with Spring Framework conventions (if reviewing Spring code)
- Knowledge of common security vulnerabilities (OWASP Top 10)
- 掌握Java 8+的Stream API、Optional、Lambda表达式
- 了解Java 11+的var、String方法、Collection.toArray()
- 熟悉Java 14+的Records、Switch表达式、文本块
- 理解Java 17+的密封类、模式匹配
- 理解SOLID原则和设计模式
- 熟悉Spring Framework规范(如果审查Spring代码)
- 了解常见安全漏洞(OWASP Top 10)
Review Checklist
审查检查清单
Use this checklist to ensure comprehensive coverage:
Design & Architecture:
- SOLID principles followed
- Proper layer separation (Controller/Service/Repository)
- Dependency injection used correctly
- Interfaces used for abstraction
- Design patterns applied appropriately
Code Quality:
- Methods are focused and under 50 lines
- No code duplication (DRY)
- Clear, descriptive naming
- No magic numbers or strings
- Proper visibility modifiers (private, protected, public)
Error Handling:
- Appropriate exception types used
- No empty catch blocks
- Meaningful error messages
- Exception chaining preserved
- Resources cleaned up in finally or try-with-resources
Modern Java:
- Stream API used where appropriate
- Optional used instead of null returns
- Records used for DTOs (Java 14+)
- Switch expressions used (Java 14+)
- Text blocks for multi-line strings (Java 15+)
Thread Safety:
- Shared mutable state identified
- Proper synchronization if needed
- Immutable objects preferred
- Thread-safe collections used
Security:
- No hardcoded credentials
- Input validation present
- SQL injection prevention (PreparedStatement)
- No path traversal vulnerabilities
- Sensitive data not logged
Performance:
- No premature optimization
- Efficient algorithms used
- Proper use of collections
- Stream operations optimized
- Database N+1 queries avoided
使用此清单确保审查全面覆盖:
设计与架构:
- 遵循SOLID原则
- 正确的分层(控制器/服务/仓库)
- 依赖注入使用正确
- 使用接口实现抽象
- 合理应用设计模式
代码质量:
- 方法聚焦且不超过50行
- 无代码重复(遵循DRY原则)
- 清晰、描述性的命名
- 无魔法值和魔法字符串
- 正确的可见性修饰符(private、protected、public)
错误处理:
- 使用合适的异常类型
- 无空catch块
- 有意义的错误信息
- 保留异常链
- 在finally或try-with-resources中清理资源
现代Java:
- 合适场景下使用Stream API
- 使用Optional替代null返回值
- 使用Records作为DTO(Java 14+)
- 使用Switch表达式(Java 14+)
- 使用文本块处理多行字符串(Java 15+)
线程安全:
- 识别共享可变状态
- 必要时使用正确的同步
- 优先使用不可变对象
- 使用线程安全的集合
安全:
- 无硬编码凭证
- 存在输入验证
- 防止SQL注入(使用PreparedStatement)
- 无路径遍历漏洞
- 敏感数据未被日志记录
性能:
- 无过早优化
- 使用高效算法
- 合理使用集合
- Stream操作优化
- 避免数据库N+1查询
Output Format
输出格式
Always structure review output as:
markdown
undefined审查输出需始终遵循以下结构:
markdown
undefinedJava Code Review: [ClassName or Package]
Java Code Review: [ClassName or Package]
Summary
Summary
- Files reviewed: X
- Critical issues: X
- High priority issues: X
- Medium priority issues: X
- Low priority issues: X
- Files reviewed: X
- Critical issues: X
- High priority issues: X
- Medium priority issues: X
- Low priority issues: X
Critical Issues (Fix Immediately)
Critical Issues (Fix Immediately)
[List with file:line, description, fix]
[List with file:line, description, fix]
High Priority Issues (Fix Soon)
High Priority Issues (Fix Soon)
[List with file:line, description, fix]
[List with file:line, description, fix]
Medium Priority Issues (Improve When Possible)
Medium Priority Issues (Improve When Possible)
[List with file:line, description, fix]
[List with file:line, description, fix]
Low Priority Issues (Nice to Have)
Low Priority Issues (Nice to Have)
[List with file:line, description, fix]
[List with file:line, description, fix]
Positive Findings
Positive Findings
[Call out well-written code and good practices]
[Call out well-written code and good practices]
Overall Assessment
Overall Assessment
[Summary paragraph with key recommendations]
undefined[Summary paragraph with key recommendations]
undefinedError Handling
错误处理
If review cannot be completed:
- File Not Found: Verify path and use Glob to search for Java files
- Cannot Parse Code: Note syntax errors preventing analysis
- Incomplete Context: Request additional files for proper review (e.g., parent classes, interfaces)
- Ambiguous Requirements: Ask for specific focus areas (security, performance, etc.)
Always fail-fast with clear error messages rather than providing incomplete reviews.
如果无法完成审查:
- 文件未找到: 验证路径,使用Glob搜索Java文件
- 无法解析代码: 记录阻碍分析的语法错误
- 上下文不完整: 请求额外文件以进行正确审查(如父类、接口)
- 需求不明确: 询问具体的审查重点(安全、性能等)
始终快速失败并返回清晰的错误信息,而非提供不完整的审查结果。