阿里巴巴 Java 开发手册学习总结(一):编程规约
Published in:2025-06-08 | category: Java

阿里巴巴 Java 开发手册(《Java 开发手册》,又称”泰山版”)是国内 Java 开发领域最有影响力的规范文档之一。本系列梳理其中对日常编码影响最大的规则,并结合实际踩坑经验做补充说明。

一、命名规范

包名、类名、方法名

类型规范反例
包名全小写,单数形式com.ali.Utils(不用复数)
类名UpperCamelCaseuserService(应为 UserService)
方法名/变量名lowerCamelCaseGetUserInfo(应为 getUserInfo)
常量全大写下划线maxCount(应为 MAX_COUNT)

禁止使用的命名

  • a, b, c 这类无意义单字母(循环变量 i/j/k 除外)
  • doiffor 等关键字
  • 中文拼音:geYongHuXinXi()(拼音命名一眼看不懂,不如用英文)

POJO 类命名

手册要求:

  • 数据对象:xxxDO(Database Object)
  • 数据传输对象:xxxDTO
  • 视图对象:xxxVO
  • 持久化用的查询条件:xxxQuery

二、常量定义

不允许任何魔法值

1
2
3
4
5
// 错误
if (user.getStatus() == 2) { ... }

// 正确
if (user.getStatus() == UserStatusEnum.LOCKED.getCode()) { ... }

long 型字面量后加 L

1
2
long timeout = 3000L;   // 正确
long timeout = 3000; // 可能造成精度丢失误解

三、代码格式

空行和换行

手册强调代码的”段落感”——同一语义的代码放一起,不同语义之间空一行。这一点很多人忽视,导致几十行的方法读起来密密麻麻,找不到结构。

单个方法不超过 80 行

这个限制的原因不是任意规定,而是:超过 80 行的方法往往承担了多个职责,违反单一职责原则,且难以测试。

遇到超长方法的处理思路:

  1. 抽取私有方法
  2. 引入策略模式/模板方法拆分分支
  3. 把数据准备、逻辑处理、结果组装分离

四、OOP 规约

不要用对象引用访问静态方法

1
2
3
4
5
6
// 错误
MyClass obj = new MyClass();
obj.staticMethod();

// 正确
MyClass.staticMethod();

静态方法属于类,用对象引用调用会让阅读者误以为这是实例方法,造成混淆。

所有 POJO 属性不用包装类型,推荐基础数据类型

等等,手册原话是反过来的:POJO 类属性必须使用包装类型(Integer 而不是 int),原因是 RPC 接口返回可能为 null,如果是基本类型会导致 NPE。

1
2
3
4
5
// POJO 类
public class UserDTO {
private Integer age; // 正确,可以表达 null(未知)
// private int age; // 错误,无法区分"0岁"和"未填写"
}

局部变量推荐用基本类型:

1
int count = list.size();   // 局部变量,不会为 null

equals 方法

1
2
3
4
5
6
7
8
// 错误(如果 str 为 null,NPE)
if (str.equals("hello")) { ... }

// 正确(常量在左,避免 NPE)
if ("hello".equals(str)) { ... }

// 更推荐
if (Objects.equals(str, "hello")) { ... }

五、集合处理

ArrayList 的 subList 返回的不是 ArrayList

1
2
3
4
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
List<String> sub = list.subList(0, 2);
// sub 是 AbstractList$SubList,不是 ArrayList
// 不能直接强转为 ArrayList,会 ClassCastException

如果需要独立的 ArrayList:

1
List<String> sub = new ArrayList<>(list.subList(0, 2));

不要在 foreach 里删除/添加集合元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 错误,ConcurrentModificationException
for (String item : list) {
if (item.equals("del")) {
list.remove(item);
}
}

// 正确,使用 Iterator
Iterator<String> it = list.iterator();
while (it.hasNext()) {
if (it.next().equals("del")) {
it.remove();
}
}

// 或者用 removeIf(Java 8+)
list.removeIf(item -> item.equals("del"));

Map 遍历用 entrySet

1
2
3
4
5
6
7
8
9
10
// 低效:先获取 key,再用 key 取 value(两次查找)
for (String key : map.keySet()) {
String value = map.get(key);
}

// 推荐:entrySet 一次获取 key+value
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
}

小结

第一篇整理了命名、常量、格式、OOP、集合这五个方向的核心规则。下一篇将整理并发编程、异常处理和 MySQL 规约。

Prev:
阿里巴巴 Java 开发手册学习总结(二):并发、异常与日志
Next:
Kafka 生产者