Java 编程规约详解:从命名到并发的最佳实践
在团队开发中,统一的编程规范是提升代码质量、降低协作成本的核心保障。良好的代码不仅要能正确运行,更要具备可读性、可维护性和可扩展性。本文将从命名风格、常量定义、代码格式、OOP 规约等多个维度,详解 Java 编程中的核心规约,帮助开发者写出更规范的代码。
一、命名风格:代码的 “脸面”
命名是代码的第一印象,规范的命名能让代码 “自解释”,减少理解成本。以下是命名的核心准则:
1. 基础命名禁忌
- 命名不能以下划线(
_)或美元符号($)开头 / 结尾。
反例:_name、name_、$user、user$ - 禁止拼音与英文混合命名,更不允许直接使用中文。纯拼音命名也应避免,优先使用正确的英文拼写。
反例:getPingfenByName()(“评分” 应译为getScoreByName)、int 某变量 = 3 - 杜绝无意义缩写,避免 “望文不知义”。
反例:AbsClass(应为AbstractClass)、condi(应为condition)
2. 各类元素命名规则
MarcoPolo、UserDO、XmlService;例外:DO/BO/DTO/VO等缩写可大写localValue、getHttpMessage()、inputUserIdMAX_STOCK_COUNT(语义完整,长度建议不超过 25 字符);反例:MAX_COUNT(语义模糊)Abstract或Base开头AbstractTranslator、BaseServiceException结尾BusinessException、NullPointerExceptionTest结尾UserServiceTest、OrderDAOImplTestint[] arrayDemo;反例:int arrayDemo[](C 语言风格不推荐)is前缀private Boolean deleted;(getter 为isDeleted());反例:private Boolean isDeleted;(序列化可能出错)com.aaa.ai.util;类名若有复数含义可使用复数,如MessageUtilsImpl后缀CacheService,实现类CacheServiceImpl;能力接口用形容词(如Translatable)Enum后缀,成员全大写ProcessStatusEnum,成员SUCCESS、UNKNOWN_REASON二、常量定义:拒绝 “魔法值”
常量是代码中固定不变的值,规范定义能避免重复硬编码,降低修改成本。
核心准则
- 禁止 “魔法值”(未预先定义的常量)直接出现在代码中。
反例:String key = \"Id#aaa_\" + tradeId;(应定义常量TRACE_ID_PREFIX = \"Id#aaa_\") long/Long赋值时,数值后必须用大写L(小写l易与数字1混淆)。
正例:Long num = 2L;;反例:Long num = 2l;
三、代码格式:整洁的 “排版”
统一的代码格式能减少视觉干扰,提升阅读效率。
关键规范
- 大括号约定:左大括号前不换行,后换行;右大括号前换行,后若有
else不换行,否则换行。
正例:if (flag == 0) { System.out.println(\"hello\");} else { System.out.println(\"world\");} - 空格使用:关键字(
if/for等)与括号间加空格;二目 / 三目运算符左右加空格;小括号与内容间无空格。
反例:if(flag==0)、int a=1+2 - 缩进:采用 4 个空格缩进,禁止使用
tab字符。 - 单行长度:不超过 120 字符,超出需换行(第二行缩进 4 空格,运算符与下文一起换行)。
正例:sb.append(\"begin\"). append(\"very long content 1 ..............................................\"). append(\"end\"); - 注释格式:双斜线与内容间有且仅有一个空格,如
// 这是注释。
四、OOP 规约:面向对象的 “规矩”
面向对象编程需遵循封装、继承、多态原则,以下是核心规范:
1. 类与方法
- 覆写方法必须加
@Override注解,避免因方法签名错误导致覆写失败。 - 外部依赖的接口禁止修改方法签名,过时接口需加
@Deprecated注解并说明替代方案。 - 禁止使用过时的类或方法(如
URLDecoder.decode(String)应改为decode(String, String))。
2. equals 与包装类
- 调用
equals时,用常量或确定有值的对象作为调用者,避免空指针异常。
正例:\"alice\".equals(name);反例:name.equals(\"alice\")(name为null时抛异常) - 包装类对象比较必须用
equals(Integer在-128~127外的对象==判断会失效)。 - 基本类型与包装类使用标准:POJO 属性、RPC 参数 / 返回值用包装类;局部变量用基本类型。
3. POJO 类规范
- 不设定属性默认值(避免更新时意外覆盖)。
- 必须实现
toString()方法(便于异常排查)。 - 禁止同时存在
isXxx()和getXxx()方法(框架解析可能冲突)。
五、集合处理:避免 “坑点”
集合是 Java 开发的高频工具,规范使用能减少异常。
核心准则
- 重写
equals必须重写hashCode(保证Set去重、Map键唯一)。 ArrayList.subList()返回的是视图,修改原集合会导致子列表抛ConcurrentModificationException。- 集合转数组用
toArray(T[] array),传入与集合大小一致的数组。
正例:List list = new ArrayList();String[] array = new String[list.size()];array = list.toArray(array); - 禁止在
foreach循环中增删元素,需用Iterator(并发场景需加锁)。 Arrays.asList()返回的集合不可修改(add/remove会抛异常)。
六、并发处理:线程安全的 “底线”
高并发场景下,线程安全是核心挑战,需遵循以下规范:
- 线程池必须通过
ThreadPoolExecutor创建(禁止用Executors,避免 OOM 风险)。 - 线程 / 线程池命名需有意义(便于问题回溯),如
TimerTaskThread。 SimpleDateFormat线程不安全,禁止定义为static变量,推荐用ThreadLocal或 JDK8 的DateTimeFormatter。- 加锁需保持顺序一致(避免死锁),优先用无锁结构,缩小锁范围。
- 并发修改同一记录需加锁(应用层锁 / 缓存锁 / 数据库乐观锁),乐观锁重试次数不小于 3 次。
七、控制语句与注释:逻辑与说明的 “清晰化”
控制语句
switch必须包含default分支,每个case需用break/return终止或注释说明流程。if/for等语句必须用大括号,即使只有一行代码(避免逻辑漏洞)。
注释规范
- 类、属性、方法需用 Javadoc 注释(
/** 内容 */),说明功能、参数、返回值。 - 抽象方法必须注释实现要求,枚举字段需说明用途。
- 方法内部单行注释用
//,多行行注释用/* */,与代码对齐。
总结
编程规约不是束缚,而是团队协作的 “共同语言”。遵循这些规范能减少 bug、提升代码可读性、降低维护成本。无论是命名的细节、集合的使用,还是并发的处理,每一条规约背后都是无数实践总结的经验。希望本文能帮助开发者养成良好的编码习惯,写出 “别人看得懂、自己忘不掉” 的高质量代码。


