推行阿里规约时,真正卡住团队的往往不是条款本身,而是那些手册里一笔带过、写起来却容易翻车的细节。下面按实际踩坑频率从高到低说。
命名:接口别加 I 前缀
类名用 Upper Camel Case,方法名用 lower Camel Case,这两条基本没人错。
真正容易翻车的是接口命名。抽象类叫 AbstractXxxHelper 没问题,但接口加 I 前缀(IUserService)不符合阿里推荐,直接用 UserService。
这个细节后期重构代价很大——改一个接口名,所有实现类和调用方全要跟着动。
异常:别 catch Exception 了事
阿里规约明确不建议捕获 RuntimeException、Exception 或 Throwable。
图省事写 catch (Exception e) 再打印堆栈,底层一出问题根本定位不到具体行。正确做法是按需捕获具体异常,要么当场处理,要么抛给上层。
这里有个坑:finally 块里写 return 会吞掉 try 中的异常。之前一次线上事故就是 finally 里 return,导致场景逻辑走进了错误分支。
try {
doSomething();
} catch (IOException e) {
log.error("io failed", e);
throw new BizException(e);
} finally {
// 不要在这里 return,否则异常被吞
cleanup();
}
集合:初始容量不是可选项
ArrayList 在已知数据量时建议设定初始容量,否则频繁扩容拖性能。
HashMap 的容量计算同样要用变参方法,避免重复计算。高并发下不设初始容量,很容易 OOM 或大量时间耗在 resize 上。
一次压测中,同事用 HashMap 处理几万条数据没设初始容量,CPU 直接飙到 99%,加上初始容量后立刻降下来。

格式化:统一风格靠工具不靠自觉
小组里有人用 tab、有人用空格,git diff 里全是缩进差异,review 根本没法看。
后来强制装阿里规约插件,提交前自动格式化。插件还能顺带查出魔法值、重复代码、未使用变量,比人工 review 高效得多。
线程安全:两个高频雷区
SimpleDateFormat 不是线程安全的,多线程共用会解析出错乱结果,改用 DateTimeFormatter。
线程池不要用 Executors 创建,要手动 new ThreadPoolExecutor 并显式设置参数。
我们一个服务用 Executors.newFixedThreadPool 没指定队列大小,任务积压直接导致内存泄漏。补充一个实测要点:手动创建时务必传入有界队列并配置拒绝策略,否则和用 Executors 没区别。
字符串拼接这类细节
字符串拼接用 StringBuilder,别直接用加号,尤其在循环里。
这些与业务无关但影响性能的细节,恰恰决定系统稳定性。规范不是束缚,是无数踩坑换来的最低成本。
坚持一个月,代码风格统一后维护成本会明显下降。