阿里巴巴 Java 开发手册(《Java 开发手册》,又称”泰山版”)是国内 Java 开发领域最有影响力的规范文档之一。本系列梳理其中对日常编码影响最大的规则,并结合实际踩坑经验做补充说明。
一、命名规范
包名、类名、方法名
| 类型 | 规范 | 反例 |
|---|
| 包名 | 全小写,单数形式 | com.ali.Utils(不用复数) |
| 类名 | UpperCamelCase | userService(应为 UserService) |
| 方法名/变量名 | lowerCamelCase | GetUserInfo(应为 getUserInfo) |
| 常量 | 全大写下划线 | maxCount(应为 MAX_COUNT) |
禁止使用的命名
a, b, c 这类无意义单字母(循环变量 i/j/k 除外)do、if、for 等关键字- 中文拼音:
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 行的方法往往承担了多个职责,违反单一职责原则,且难以测试。
遇到超长方法的处理思路:
- 抽取私有方法
- 引入策略模式/模板方法拆分分支
- 把数据准备、逻辑处理、结果组装分离
四、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
| public class UserDTO { private Integer age; }
|
而局部变量推荐用基本类型:
1
| int count = list.size();
|
equals 方法
1 2 3 4 5 6 7 8
| if (str.equals("hello")) { ... }
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);
|
如果需要独立的 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
| for (String item : list) { if (item.equals("del")) { list.remove(item); } }
Iterator<String> it = list.iterator(); while (it.hasNext()) { if (it.next().equals("del")) { it.remove(); } }
list.removeIf(item -> item.equals("del"));
|
Map 遍历用 entrySet
1 2 3 4 5 6 7 8 9 10
| for (String key : map.keySet()) { String value = map.get(key); }
for (Map.Entry<String, String> entry : map.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); }
|
小结
第一篇整理了命名、常量、格式、OOP、集合这五个方向的核心规则。下一篇将整理并发编程、异常处理和 MySQL 规约。