java-dev
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseJava Development - Alibaba Coding Guidelines
Java开发 - 阿里巴巴编码规范
Overview
概述
This skill provides comprehensive Java development guidance based on the Alibaba Java Coding Guidelines (Songshan Edition). It ensures all Java code follows industry best practices covering naming conventions, coding standards, concurrency, exception handling, database design, security, testing, and architectural design.
本指南基于《阿里巴巴Java开发手册(嵩山版)》提供全面的Java开发指导,确保所有Java代码遵循涵盖命名规范、编码标准、并发处理、异常处理、数据库设计、安全、测试及架构设计的行业最佳实践。
Core Principles
核心原则
When writing Java code, always follow these fundamental principles:
- Code Readability: Write code that is easy to understand and maintain
- Consistency: Follow consistent naming and formatting conventions
- Safety First: Prevent common pitfalls like NPE, SQL injection, and concurrency issues
- Performance Awareness: Consider performance implications of design decisions
- Test Coverage: Ensure adequate unit test coverage for critical code
编写Java代码时,请始终遵循以下基本原则:
- 代码可读性:编写易于理解和维护的代码
- 一致性:遵循统一的命名和格式规范
- 安全优先:避免空指针异常(NPE)、SQL注入、并发问题等常见陷阱
- 性能意识:考虑设计决策对性能的影响
- 测试覆盖:确保关键代码有足够的单元测试覆盖
Quick Reference
快速参考
Naming Conventions
命名规范
- Classes: UpperCamelCase (e.g., ,
UserService)OrderController - Methods/Variables: lowerCamelCase (e.g., ,
getUserById)userName - Constants: UPPER_SNAKE_CASE (e.g., ,
MAX_COUNT)DEFAULT_SIZE - Packages: lowercase, single word preferred (e.g., )
com.company.module
- 类:大驼峰式(UpperCamelCase)(例如:,
UserService)OrderController - 方法/变量:小驼峰式(lowerCamelCase)(例如:,
getUserById)userName - 常量:大写下划线分隔(UPPER_SNAKE_CASE)(例如:,
MAX_COUNT)DEFAULT_SIZE - 包:小写,优先使用单个单词(例如:)
com.company.module
Common Patterns
通用命名模式
- Abstract classes: or
Abstract*prefixBase* - Exception classes: suffix
*Exception - Test classes: suffix
*Test - Service implementations: suffix
*Impl - Boolean variables: No prefix in POJO classes
is - DAO methods: (single),
get*(multiple),list*,count*,save*,remove*update*
- 抽象类:使用或
Abstract*前缀Base* - 异常类:使用后缀
*Exception - 测试类:使用后缀
*Test - 服务实现类:使用后缀
*Impl - 布尔变量:POJO类中不使用前缀
is - DAO方法:(单个查询)、
get*(多个查询)、list*(统计)、count*(保存)、save*(删除)、remove*(更新)update*
Critical Rules
关键规则
- ❌ Never use magic numbers directly in code
- ❌ Never catch exceptions without handling them
- ❌ Never use to compare wrapper types (use
==)equals() - ❌ Never create threads directly (use thread pools)
- ❌ Never use in SQL queries
SELECT * - ✅ Always use parameterized queries to prevent SQL injection
- ✅ Always specify initial capacity for collections when size is known
- ✅ Always close resources in blocks or use try-with-resources
finally - ✅ Always validate external inputs
- ❌ 切勿在代码中直接使用魔法值
- ❌ 切勿捕获异常却不做处理
- ❌ 切勿使用比较包装类型(请使用
==)equals() - ❌ 切勿直接创建线程(请使用线程池)
- ❌ SQL查询中切勿使用
SELECT * - ✅ 始终使用参数化查询防止SQL注入
- ✅ 当已知集合大小时,始终指定初始容量
- ✅ 始终在块中关闭资源,或使用try-with-resources语法
finally - ✅ 始终验证外部输入
Workflow
工作流程
1. Before Writing Code
1. 编码前准备
Check the detailed guidelines:
- For naming rules → See naming-conventions.md
- For coding standards → See coding-standards.md
- For concurrency → See concurrency.md
- For database design → See database.md
- For security → See security.md
- For testing → See testing.md
- For design patterns → See design.md
查阅详细指南:
- 命名规则 → 参考 naming-conventions.md
- 编码标准 → 参考 coding-standards.md
- 并发处理 → 参考 concurrency.md
- 数据库设计 → 参考 database.md
- 安全规范 → 参考 security.md
- 测试规范 → 参考 testing.md
- 设计模式 → 参考 design.md
2. Writing Code
2. 编码过程
Apply the following checks as you write:
Naming
- Class names use UpperCamelCase
- Method/variable names use lowerCamelCase
- Constants use UPPER_SNAKE_CASE
- Meaningful English names (no pinyin)
Code Structure
- Methods under 80 lines
- Single responsibility per class/method
- Proper access modifiers (private by default)
- Use for overridden methods
@Override
Common Pitfalls to Avoid
java
// ❌ Wrong: Magic numbers
if (status == 1) { ... }
// ✅ Correct: Named constants
private static final int STATUS_ACTIVE = 1;
if (status == STATUS_ACTIVE) { ... }
// ❌ Wrong: Comparing wrapper types with ==
Integer a = 128;
Integer b = 128;
if (a == b) { ... } // May fail!
// ✅ Correct: Use equals()
if (a.equals(b)) { ... }
// ❌ Wrong: Empty catch block
try {
doSomething();
} catch (Exception e) {
// Silent failure
}
// ✅ Correct: Handle or rethrow
try {
doSomething();
} catch (Exception e) {
logger.error("Failed to do something", e);
throw new BusinessException("Operation failed", e);
}
// ❌ Wrong: Creating threads directly
new Thread(() -> doWork()).start();
// ✅ Correct: Use thread pool
ExecutorService executor = new ThreadPoolExecutor(
corePoolSize, maxPoolSize, keepAliveTime,
TimeUnit.SECONDS, new LinkedBlockingQueue<>(),
new ThreadFactoryBuilder().setNameFormat("worker-%d").build()
);
executor.submit(() -> doWork());编码时请执行以下检查:
命名检查
- 类名使用大驼峰式
- 方法/变量名使用小驼峰式
- 常量使用大写下划线分隔
- 使用有意义的英文名称(禁止使用拼音)
代码结构
- 方法代码不超过80行
- 类/方法遵循单一职责原则
- 使用正确的访问修饰符(默认私有)
- 重写方法时添加注解
@Override
需避免的常见陷阱
java
// ❌ 错误:使用魔法值
if (status == 1) { ... }
// ✅ 正确:使用命名常量
private static final int STATUS_ACTIVE = 1;
if (status == STATUS_ACTIVE) { ... }
// ❌ 错误:使用==比较包装类型
Integer a = 128;
Integer b = 128;
if (a == b) { ... } // 可能失败!
// ✅ 正确:使用equals()
if (a.equals(b)) { ... }
// ❌ 错误:空catch块
try {
doSomething();
} catch (Exception e) {
// 静默失败
}
// ✅ 正确:处理或重新抛出异常
try {
doSomething();
} catch (Exception e) {
logger.error("Failed to do something", e);
throw new BusinessException("Operation failed", e);
}
// ❌ 错误:直接创建线程
new Thread(() -> doWork()).start();
// ✅ 正确:使用线程池
ExecutorService executor = new ThreadPoolExecutor(
corePoolSize, maxPoolSize, keepAliveTime,
TimeUnit.SECONDS, new LinkedBlockingQueue<>(),
new ThreadFactoryBuilder().setNameFormat("worker-%d").build()
);
executor.submit(() -> doWork());3. Database Operations
3. 数据库操作
Table Design
- Table names: lowercase with underscores (e.g., )
user_order - Required fields: ,
id,create_timeupdate_time - Boolean fields: prefix (e.g.,
is_*)is_deleted - Use for IDs
BIGINT UNSIGNED - Use for monetary values (never
DECIMALorFLOAT)DOUBLE
SQL Best Practices
java
// ✅ Correct: Parameterized query
String sql = "SELECT id, user_name, email FROM user WHERE id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setLong(1, userId);
// ✅ Correct: MyBatis parameter binding
@Select("SELECT * FROM user WHERE user_name = #{userName}")
User selectByUserName(@Param("userName") String userName);
// ❌ Wrong: String concatenation (SQL injection risk!)
String sql = "SELECT * FROM user WHERE user_name = '" + userName + "'";表设计规范
- 表名:小写加下划线(例如:)
user_order - 必填字段:、
id、create_timeupdate_time - 布尔字段:使用前缀(例如:
is_*)is_deleted - ID字段使用类型
BIGINT UNSIGNED - 金额字段使用类型(禁止使用
DECIMAL或FLOAT)DOUBLE
SQL最佳实践
java
// ✅ 正确:参数化查询
String sql = "SELECT id, user_name, email FROM user WHERE id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setLong(1, userId);
// ✅ 正确:MyBatis参数绑定
@Select("SELECT * FROM user WHERE user_name = #{userName}")
User selectByUserName(@Param("userName") String userName);
// ❌ 错误:字符串拼接(存在SQL注入风险!)
String sql = "SELECT * FROM user WHERE user_name = '" + userName + "'";4. Exception Handling
4. 异常处理
Exception Hierarchy
- Use specific exception types
- Checked exceptions for recoverable errors
- Unchecked exceptions for programming errors
- Always include context in exception messages
java
// ✅ Correct exception handling
public User getUserById(Long userId) {
if (userId == null) {
throw new IllegalArgumentException("userId cannot be null");
}
User user = userDao.selectById(userId);
if (user == null) {
throw new NotFoundException("User not found: " + userId);
}
return user;
}
// ✅ Correct logging with exception
try {
processOrder(order);
} catch (Exception e) {
logger.error("Failed to process order, orderId: {}", order.getId(), e);
throw new BusinessException("订单处理失败", e);
}异常层级规范
- 使用具体的异常类型
- 可恢复错误使用受检异常
- 编程错误使用非受检异常
- 异常消息中始终包含上下文信息
java
// ✅ 正确的异常处理
public User getUserById(Long userId) {
if (userId == null) {
throw new IllegalArgumentException("userId cannot be null");
}
User user = userDao.selectById(userId);
if (user == null) {
throw new NotFoundException("User not found: " + userId);
}
return user;
}
// ✅ 正确的异常日志记录
try {
processOrder(order);
} catch (Exception e) {
logger.error("Failed to process order, orderId: {}", order.getId(), e);
throw new BusinessException("订单处理失败", e);
}5. Concurrency
5. 并发处理
Thread Safety Rules
- Use instead of
ThreadPoolExecutorExecutors - Name your threads for debugging
- Use for visibility,
volatilefor atomic operationsAtomicXxx - Avoid in multi-threaded code (use
SimpleDateFormat)DateTimeFormatter - Clean up variables
ThreadLocal
java
// ✅ Correct: Thread pool with proper configuration
ThreadPoolExecutor executor = new ThreadPoolExecutor(
10, // corePoolSize
20, // maximumPoolSize
60L, // keepAliveTime
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100),
new ThreadFactoryBuilder().setNameFormat("order-processor-%d").build(),
new ThreadPoolExecutor.CallerRunsPolicy()
);
// ✅ Correct: ThreadLocal cleanup
private static final ThreadLocal<User> USER_CONTEXT = new ThreadLocal<>();
public void processRequest() {
try {
USER_CONTEXT.set(getCurrentUser());
// Process request
} finally {
USER_CONTEXT.remove(); // Critical: prevent memory leak
}
}线程安全规则
- 使用而非
ThreadPoolExecutorExecutors - 为线程命名以便调试
- 使用保证可见性,
volatile实现原子操作AtomicXxx - 多线程环境中避免使用(请使用
SimpleDateFormat)DateTimeFormatter - 清理变量
ThreadLocal
java
// ✅ 正确:配置合理的线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
10, // corePoolSize
20, // maximumPoolSize
60L, // keepAliveTime
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100),
new ThreadFactoryBuilder().setNameFormat("order-processor-%d").build(),
new ThreadPoolExecutor.CallerRunsPolicy()
);
// ✅ 正确:清理ThreadLocal
private static final ThreadLocal<User> USER_CONTEXT = new ThreadLocal<>();
public void processRequest() {
try {
USER_CONTEXT.set(getCurrentUser());
// 处理请求
} finally {
USER_CONTEXT.remove(); // 关键操作:防止内存泄漏
}
}6. Security
6. 安全规范
Input Validation
- Validate all external inputs
- Use parameterized queries (never string concatenation)
- Sanitize HTML output to prevent XSS
- Implement CSRF protection
- Mask sensitive data in logs
java
// ✅ Correct: Input validation
public void createUser(UserCreateRequest request) {
if (StringUtils.isBlank(request.getUserName())) {
throw new ValidationException("用户名不能为空");
}
if (!ValidationUtils.isValidMobile(request.getMobile())) {
throw new ValidationException("手机号格式不正确");
}
// Process...
}
// ✅ Correct: Sensitive data masking
logger.info("User login, mobile: {}", maskMobile(user.getMobile()));输入验证
- 验证所有外部输入
- 使用参数化查询(禁止字符串拼接)
- 对HTML输出进行清理以防止XSS攻击
- 实现CSRF防护
- 日志中屏蔽敏感数据
java
// ✅ 正确:输入验证
public void createUser(UserCreateRequest request) {
if (StringUtils.isBlank(request.getUserName())) {
throw new ValidationException("用户名不能为空");
}
if (!ValidationUtils.isValidMobile(request.getMobile())) {
throw new ValidationException("手机号格式不正确");
}
// 处理逻辑...
}
// ✅ 正确:敏感数据屏蔽
logger.info("User login, mobile: {}", maskMobile(user.getMobile()));7. Unit Testing
7. 单元测试
Testing Standards
- Test class naming:
*Test - Test method naming:
test* - Target coverage: 70% statement coverage minimum
- Use JUnit 5 + Mockito
- Follow BCDE principle (Border, Correct, Design, Error)
java
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
@Mock
private UserDao userDao;
@InjectMocks
private UserService userService;
@Test
@DisplayName("根据ID获取用户 - 正常情况")
public void testGetUserById_Success() {
// Given
Long userId = 1L;
User mockUser = new User();
mockUser.setId(userId);
mockUser.setUserName("test");
when(userDao.selectById(userId)).thenReturn(mockUser);
// When
User result = userService.getUserById(userId);
// Then
assertNotNull(result);
assertEquals(userId, result.getId());
verify(userDao, times(1)).selectById(userId);
}
@Test
@DisplayName("根据ID获取用户 - 参数为null")
public void testGetUserById_NullParameter() {
assertThrows(IllegalArgumentException.class, () -> {
userService.getUserById(null);
});
}
}测试标准
- 测试类命名:
*Test - 测试方法命名:
test* - 目标覆盖率:至少70%语句覆盖率
- 使用JUnit 5 + Mockito框架
- 遵循BCDE原则(边界、正确、设计、错误)
java
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
@Mock
private UserDao userDao;
@InjectMocks
private UserService userService;
@Test
@DisplayName("根据ID获取用户 - 正常情况")
public void testGetUserById_Success() {
// 给定条件
Long userId = 1L;
User mockUser = new User();
mockUser.setId(userId);
mockUser.setUserName("test");
when(userDao.selectById(userId)).thenReturn(mockUser);
// 执行操作
User result = userService.getUserById(userId);
// 断言结果
assertNotNull(result);
assertEquals(userId, result.getId());
verify(userDao, times(1)).selectById(userId);
}
@Test
@DisplayName("根据ID获取用户 - 参数为null")
public void testGetUserById_NullParameter() {
assertThrows(IllegalArgumentException.class, () -> {
userService.getUserById(null);
});
}
}Code Review Checklist
代码评审检查清单
When reviewing Java code, verify:
评审Java代码时,请验证以下内容:
Naming & Style
命名与风格
- Class names use UpperCamelCase
- Method/variable names use lowerCamelCase
- Constants use UPPER_SNAKE_CASE
- No magic numbers in code
- Meaningful English names (no pinyin)
- 类名使用大驼峰式
- 方法/变量名使用小驼峰式
- 常量使用大写下划线分隔
- 代码中无魔法值
- 使用有意义的英文名称(无拼音)
Code Quality
代码质量
- Methods under 80 lines
- Single responsibility principle followed
- Proper access modifiers used
- No duplicate code
- Proper exception handling
- 方法代码不超过80行
- 遵循单一职责原则
- 使用正确的访问修饰符
- 无重复代码
- 异常处理合理
Safety
安全性
- No NPE risks (null checks where needed)
- Wrapper types compared with , not
equals()== - Resources properly closed (try-with-resources or finally)
- Thread-safe if used in concurrent context
- Input validation for external data
- 无NPE风险(必要处进行空值检查)
- 包装类型使用比较,而非
equals()== - 资源已正确关闭(try-with-resources或finally块)
- 并发场景下保证线程安全
- 外部数据已做输入验证
Database
数据库
- Parameterized queries (no SQL injection risk)
- Specific columns selected (no )
SELECT * - Proper indexes defined
- Transaction boundaries correct
- 使用参数化查询(无SQL注入风险)
- 查询指定列(无)
SELECT * - 已定义合理索引
- 事务边界正确
Performance
性能
- Collection initial capacity specified when size known
- String concatenation uses in loops
StringBuilder - Appropriate data structures chosen
- No unnecessary object creation in loops
- 已知集合大小时已指定初始容量
- 循环中字符串拼接使用
StringBuilder - 选择了合适的数据结构
- 循环中无不必要的对象创建
Testing
测试
- Unit tests exist for new code
- Edge cases covered
- Exception cases tested
- Mock dependencies properly
- 新代码有对应的单元测试
- 已覆盖边界场景
- 已覆盖异常场景
- 依赖模拟合理
Reference Documentation
参考文档
For detailed guidelines on specific topics, consult these reference documents:
如需特定主题的详细指南,请查阅以下参考文档:
naming-conventions.md
naming-conventions.md
Complete naming rules for classes, methods, variables, packages, and domain models.
类、方法、变量、包及领域模型的完整命名规则。
coding-standards.md
coding-standards.md
Detailed coding standards including constants, formatting, OOP rules, date/time handling, collections, and control statements.
详细编码标准,包括常量、格式、OOP规则、日期时间处理、集合及控制语句。
concurrency.md
concurrency.md
Comprehensive concurrency guidelines covering thread pools, locks, volatile, concurrent collections, and common patterns.
全面的并发处理指南,涵盖线程池、锁、volatile、并发集合及通用模式。
exception-logging.md
exception-logging.md
Exception handling best practices and logging standards using SLF4J.
异常处理最佳实践及基于SLF4J的日志标准。
database.md
database.md
MySQL database design rules, indexing strategies, SQL optimization, and ORM mapping conventions.
MySQL数据库设计规则、索引策略、SQL优化及ORM映射规范。
security.md
security.md
Security guidelines covering input validation, SQL injection prevention, XSS protection, CSRF defense, encryption, and sensitive data handling.
安全规范,涵盖输入验证、SQL注入防护、XSS防护、CSRF防御、加密及敏感数据处理。
testing.md
testing.md
Unit testing standards, frameworks (JUnit 5, Mockito), coverage requirements, and testing patterns.
单元测试标准、框架(JUnit 5、Mockito)、覆盖率要求及测试模式。
design.md
design.md
Design principles, layered architecture, domain models, design patterns, and API design conventions.
设计原则、分层架构、领域模型、设计模式及API设计规范。
Common Scenarios
常见场景
Scenario 1: Creating a New Service Class
场景1:创建新服务类
- Read naming-conventions.md for service naming rules
- Read coding-standards.md for class structure
- Read exception-logging.md for error handling
- Implement following the patterns shown above
- Add unit tests following testing.md
- 阅读naming-conventions.md了解服务命名规则
- 阅读coding-standards.md了解类结构规范
- 阅读exception-logging.md了解错误处理规范
- 按照上述模式实现代码
- 遵循testing.md添加单元测试
Scenario 2: Database Table Design
场景2:数据库表设计
- Read database.md for table design rules
- Ensure required fields: ,
id,create_timeupdate_time - Use proper data types (DECIMAL for money, BIGINT for IDs)
- Add appropriate indexes
- Create corresponding DO class following naming conventions
- 阅读database.md了解表设计规则
- 确保包含必填字段:、
id、create_timeupdate_time - 使用正确的数据类型(金额用DECIMAL,ID用BIGINT)
- 添加合理索引
- 按照命名规范创建对应的DO类
Scenario 3: Implementing Concurrent Processing
场景3:实现并发处理
- Read concurrency.md for thread pool configuration
- Use with proper parameters
ThreadPoolExecutor - Name threads for debugging
- Handle exceptions in worker threads
- Clean up ThreadLocal variables
- 阅读concurrency.md了解线程池配置
- 使用参数合理的
ThreadPoolExecutor - 为线程命名以便调试
- 处理工作线程中的异常
- 清理ThreadLocal变量
Scenario 4: Security Review
场景4:安全评审
- Read security.md for security checklist
- Verify input validation exists
- Check for SQL injection vulnerabilities
- Ensure sensitive data is masked in logs
- Verify authentication and authorization
- 阅读security.md了解安全检查清单
- 验证是否存在输入验证
- 检查SQL注入漏洞
- 确保日志中敏感数据已屏蔽
- 验证认证与授权机制
Integration with Development Workflow
与开发流程的集成
This skill integrates seamlessly into your development process:
- During Development: Reference quick rules above and detailed guidelines as needed
- Code Review: Use the checklist to ensure compliance
- Refactoring: Apply guidelines to improve existing code
- Onboarding: Use as training material for new team members
本指南可无缝集成到您的开发流程中:
- 开发过程中:参考上述快速规则及详细指南
- 代码评审:使用检查清单确保合规
- 代码重构:应用指南优化现有代码
- 新员工入职:作为培训材料使用
Summary
总结
This skill ensures all Java code adheres to Alibaba's industry-standard coding guidelines. Always prioritize:
- Readability over cleverness
- Safety over convenience
- Maintainability over quick fixes
- Standards over personal preference
When in doubt, consult the detailed reference documents for specific guidance.
本指南确保所有Java代码遵循阿里巴巴的行业标准编码规范。请始终优先考虑:
- 可读性优于技巧性
- 安全性优于便捷性
- 可维护性优于快速修复
- 标准规范优于个人偏好
如有疑问,请查阅特定主题的详细参考文档获取指导。