Java 通用语言规范
# Java 通用语言规范
# 命名约定
- 类名:使用帕斯卡命名法,如
UserController、OrderService - 方法和变量名:使用驼峰命名法,如
findUserById、isOrderValid - 常量:使用全大写下划线分隔,如
MAX_RETRY_ATTEMPTS、DEFAULT_PAGE_SIZE - 包名:使用小写,按功能模块划分,如
com.example.user.domain
# 代码风格
- 缩进:使用 4 个空格,不使用 Tab
- 行长度:每行不超过 120 个字符
- 大括号:使用 Egyptian 风格,左大括号与语句同行
- 空行:方法间使用一个空行分隔,逻辑块间使用空行分隔
# 比较与空安全
- 静态或常量在左侧比较:静态数据或变量与可能为 null 的变量比较时,使用静态变量或明确的非 null 值在左侧调用
equals,避免空指针异常
// 推荐:字面量或常量在左侧
"streakRestart".equals(param.getIntention());
AdTypeEnum.REWARD_VIDEO.getCode().equals(param.getAdSourceType());
// 不推荐:可能为 null 的变量在左侧,param.getIntention() 为 null 时会 NPE
param.getIntention().equals("streakRestart");
param.getAdSourceType().equals(AdTypeEnum.REWARD_VIDEO.getCode());
1
2
3
4
5
6
7
2
3
4
5
6
7
# 异常处理
- 检查异常使用:谨慎使用检查异常,优先使用运行时异常承载业务错误
- 异常链保留:保持异常链,不丢失原始异常信息
try {
// 可能抛出异常的代码
} catch (SpecificException e) {
throw new BusinessException("业务处理失败", e);
}
1
2
3
4
5
2
3
4
5
- 资源管理:使用 try with resources 自动管理资源
try (var reader = Files.newBufferedReader(path)) {
// 使用 reader
}
1
2
3
2
3
# 集合与流处理
集合选择:根据使用场景选择合适的集合类型
ArrayList:随机访问频繁LinkedList:插入删除操作频繁HashMap:键值对存储TreeMap:需要排序的键值对
Stream API 使用:充分利用 Stream API 进行函数式编程
List<String> activeUserNames = users.stream()
.filter(User::isActive)
.map(User::getName)
.sorted()
.toList();
1
2
3
4
5
2
3
4
5
# 并发编程
- 线程安全优先策略:优先使用不可变对象和线程安全集合
- 锁机制使用:合理使用
synchronized、ReentrantLock等锁机制 - 并发集合:根据场景选择
ConcurrentHashMap、CopyOnWriteArrayList等并发集合 - 异步编排:使用
CompletableFuture处理异步操作
CompletableFuture<String> future = CompletableFuture
.supplyAsync(this::fetchData)
.thenApply(this::processData)
.exceptionally(throwable -> "默认值");
1
2
3
4
2
3
4
# 内存管理
- 对象创建:避免在高频循环中创建不必要对象
- 字符串处理:大量字符串操作使用
StringBuilder - 集合容量:预估集合大小,合理设置初始容量,避免频繁扩容
- 弱引用使用:在缓存等场景中适当使用
WeakReference避免内存泄漏
# 泛型使用
- 类型安全:充分利用泛型提供的类型安全能力
- 通配符选择:正确使用上界通配符
? extends和下界通配符? super - 类型擦除限制:理解泛型类型擦除带来的限制,避免依赖运行时具体类型
public <T extends Comparable<T>> T findMax(List<T> list) {
return list.stream().max(Comparable::compareTo).orElse(null);
}
1
2
3
2
3
# 注解使用
- 标准注解:正确使用
@Override、@Deprecated、@SuppressWarnings等标准注解 - 自定义注解:在通用模式较多时合理创建自定义注解简化代码
- 注解处理:了解编译时与运行时注解处理机制,选择合适方案
# 测试规范
- 单元测试框架:使用 JUnit 5 编写单元测试
- 测试命名:测试方法使用行为化命名,如
shouldReturnUserWhenValidIdProvided - 断言风格:推荐使用 AssertJ 提供的流式断言
@Test
void shouldCalculateCorrectTotal() {
// Given
List<Item> items = List.of(
new Item("item1", 10.0),
new Item("item2", 20.0)
);
// When
double total = calculator.calculateTotal(items);
// Then
assertThat(total).isEqualTo(30.0);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 性能优化
- 算法复杂度:根据数据规模和访问模式选择合适的算法和数据结构
- 缓存策略:合理使用本地缓存与分布式缓存减少重复计算与 IO
- 懒加载:对高成本计算或外部依赖使用懒加载策略
- 批量处理:数据库操作和网络请求优先采用批量接口
# 代码设计质量
- 单一职责原则:每个类和方法只负责一个明确功能
- 开闭原则:对扩展开放,对修改关闭,优先通过扩展点进行功能增强
- 依赖倒置原则:依赖抽象而不是具体实现,优先面向接口编程
- 接口隔离原则:使用小而专一的接口,避免胖接口
- 代码复用:提取公共逻辑,避免复制粘贴式重复代码
# 文档与注释
- JavaDoc:为公共 API 编写完整 JavaDoc,包括参数和返回值说明
- 注释语言:复杂逻辑与关键业务流程使用中文注释,保证团队一致理解
- 方法体注释:在关键分支、非显而易见逻辑和业务含义处增加适量中文注释
- TODO 标记:使用统一风格的 TODO 标记管理待办工作
/**
* 计算用户积分
*
* @param userId 用户 ID
* @param actions 用户行为列表
* @return 计算得出的积分值
* @throws UserNotFoundException 当用户不存在时抛出
*/
public int calculatePoints(Long userId, List<UserAction> actions) {
// TODO: 实现积分计算逻辑
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 合理分类
- 当为统一功能或相似配置创建多个关联类时,根据职责与层次将相关类文件整理到合理包结构中
- 领域模型、持久化实体、传输对象分层清晰,避免单个类承担多层职责