Skip to content

编码规范

概述

编码规范(Coding Style / Code Convention)是一套约定俗成或团队统一的书写规则,用于保持代码风格一致、提高可读性和可维护性。Java 社区有 Oracle 官方约定Google Java Style、以及国内广泛参考的《阿里巴巴 Java 开发手册》等。本文从命名格式注释类与成员设计四方面归纳常用规范,便于初学者与团队协作时统一风格。

适用场景

规范用于日常编码、代码评审和新人上手;具体项目以团队或公司规范为准,本文可作为通用基础。


命名规范

命名是代码可读性的第一关。Java 对类/接口/枚举/注解方法/变量/参数常量包名有通行约定。

类、接口、枚举、注解:PascalCase

使用大驼峰(每个单词首字母大写),不含下划线。

java
// 类
public class UserService { }
public class OrderDetailDTO { }

// 接口(可与类同名风格,或形容词/能力命名)
public interface Runnable { }
public interface Serializable { }

// 枚举
public enum OrderStatus { PENDING, PAID, SHIPPED }

// 注解
public @interface Override { }
public @interface RequestMapping { }

方法、变量、参数:camelCase

使用小驼峰(首单词小写,后续单词首字母大写)。

java
public class ProductRepository {
    private int maxPageSize = 100;      // 成员变量
    private String defaultCategory;     // 成员变量

    public List<Product> findByCategory(String categoryName) {  // 方法名、参数
        int page = 0;                   // 局部变量
        return doQuery(categoryName, page);
    }
}

常量:UPPER_SNAKE_CASE

使用全大写,单词间用下划线分隔;通常配合 static final

java
public static final int MAX_RETRY_COUNT = 3;
public static final String DEFAULT_ENCODING = "UTF-8";
private static final double PI = 3.14159;

包名:全小写

包名全部小写,多个单词可连写或按域名倒序;避免使用下划线。

java
package com.example.project;
package com.example.user.service;

注意

常量若是对象类型,其引用不可变,但对象内部仍可能被修改。真正不可变时可配合不可变类(如 StringInteger)或 Collections.unmodifiableXxx


格式与排版

统一的缩进、大括号和行宽能显著降低阅读成本。

缩进与大括号

  • 缩进:通常使用 4 个空格(或团队统一的 2/4 空格),不要混用 Tab 与空格。
  • 大括号:左大括号 { 不换行,与语句同一行;右大括号 } 单独一行。控制语句即使单行也建议写大括号,避免后续加行时出错。
java
// 推荐:大括号与 if 同一行,单行也写大括号
if (condition) {
    doSomething();
}

for (int i = 0; i < list.size(); i++) {
    process(list.get(i));
}

// 不推荐:单行省略大括号,后续加行易产生逻辑错误
if (condition) doSomething();

行宽与换行

  • 行宽:单行不宜过长,常见约定 80~120 字符;超长时在合适处换行(如逗号后、运算符前),缩进对齐。
  • 空行:逻辑块之间、方法之间可空一行,避免一大块代码挤在一起。
java
// 过长时换行,下一行缩进对齐
String message = buildMessage(
        userId,
        orderId,
        OrderStatus.PAID);

注释规范

注释解释「为什么」和关键约束,而不是简单复述「是什么」。

类与公开方法

  • :用一两句话说明类的职责、使用场景;若有过期或替代方案可注明。
  • 公开方法:说明方法作用、参数含义、返回值、主要异常或前置条件。
java
/**
 * 用户订单服务:负责订单创建、状态查询与取消。
 * 所有写操作会校验用户权限。
 */
public class OrderService {

    /**
     * 根据订单 ID 查询订单;不存在时返回空 Optional。
     *
     * @param orderId 订单 ID,不能为空
     * @return 订单存在时返回 Optional.of(order),否则 Optional.empty()
     */
    public Optional<Order> findById(String orderId) {
        // ...
    }
}

关键逻辑与陷阱

复杂逻辑、业务规则、或容易误解的地方应加注释;重写 equals/hashCode、实现契约的地方也应简要说明。

java
// 重写 equals 时必须同时重写 hashCode,否则在 HashMap 等集合中行为异常
@Override
public int hashCode() {
    return Objects.hash(name, age);
}

// 使用 try-with-resources 确保流被关闭,避免资源泄漏
try (InputStream in = new FileInputStream(path)) {
    return readAll(in);
}

提示

同一文件内注释语言(中文/英文)保持一致;优先用团队或项目约定。


类与成员设计原则

编码规范不仅包括「怎么写名字」「怎么排版」,还包括一些设计习惯,避免常见坑。

可见性最小化

能用 private 就不用 protected,能用 protected 就不用 public;只把真正需要对外使用的成员设为 public,并通过方法而非暴露字段(封装)。

java
// 推荐:成员变量 private,通过方法访问
public class User {
    private String name;
    private int age;

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

// 不推荐:public 字段,外部可随意修改,难以维护
public class User {
    public String name;
    public int age;
}

equals 与 hashCode 契约

重写 equals必须同时重写 hashCode,且参与 equals 比较的字段应参与 hashCode 计算,否则在 HashMapHashSet 等基于哈希的集合中会出现逻辑错误。详见 常用类(Object / equals-hashCode)

java
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    User user = (User) o;
    return age == user.age && Objects.equals(name, user.name);
}

@Override
public int hashCode() {
    return Objects.hash(name, age);
}

单一职责与长度

  • :一个类尽量只负责一类事情;类过长(如超过数百行)时考虑按职责拆分。
  • 方法:方法不宜过长,逻辑复杂时拆成多个小方法,便于阅读和单元测试。

示例对比

命名与格式:推荐 vs 不推荐

java
// 推荐:命名清晰、常量大写、格式统一
public class OrderProcessor {
    private static final int MAX_ITEMS = 100;

    public void processOrder(Order order) {
        if (order.getItems().size() > MAX_ITEMS) {
            throw new IllegalArgumentException("订单项数量超过限制");
        }
        // ...
    }
}
java
// 不推荐:类名小写、常量小写、命名含糊
public class orderprocessor {
    private static final int maxitems = 100;

    public void ProcessOrder(Order o) {
        if (o.getItems().size() > maxitems) {
            throw new IllegalArgumentException("订单项数量超过限制");
        }
    }
}

注释与封装:推荐 vs 不推荐

java
// 推荐:类有说明、方法有说明、成员私有
/**
 * 简单内存缓存,线程不安全,仅用于单线程或已外部同步场景。
 */
public class SimpleCache<K, V> {
    private final Map<K, V> map = new HashMap<>();

    /** 若 key 已存在则覆盖并返回旧值,否则返回 null */
    public V put(K key, V value) {
        return map.put(key, value);
    }
}
java
// 不推荐:无注释、public 字段、含义不明确
public class SimpleCache<K, V> {
    public Map<K, V> map = new HashMap<>();  // 暴露内部实现

    public V put(K key, V value) { return map.put(key, value); }  // 无说明
}

注意事项

命名与类型一致

布尔类型的变量或方法命名建议使用 ishascan 等前缀,如 isEmpty()hasNext()canEdit,使含义一目了然。

与 IDE 保持一致

使用 IDE 的格式化(如格式化保存、代码风格配置)并提交前统一格式化,可减少无意义的格式差异,便于 Code Review。

避免魔法数字与魔法字符串

不要把未解释的数字、字符串直接写在逻辑里;应提取为具名常量或配置,便于修改和理解。例如用 MAX_RETRY_COUNT 代替 3,用常量代替 "UTF-8"


相关链接

基于 VitePress 构建