chinaweal-claude-code/skills/load-codestyle/style/java/java-code-style.md

8.3 KiB
Raw Permalink Blame History

Java 代码风格规范

通用 Java 项目代码风格规范,适用于所有 Java 后端项目。


1. 项目结构

包组织

  • 基础包按公司域名倒写 + 项目名,如 com.company.project
  • 按业务域划分模块,如 user/order/product/

目录结构(各模块内)

controller/          # 控制层
service/             # 服务层接口
service/impl/        # 服务层实现
entity/              # 实体层
entity/dto/          # 数据传输对象
entity/vo/           # 视图对象
mapper/              # 数据访问层MyBatis/JPA
manager/             # 复杂业务编排
checker/             # 业务校验工具

2. 命名规范

元素 规范 示例
类名 PascalCase2-41字符 UserServiceOrderController
方法名 camelCase1-31字符 getUserById()saveOrder()
变量名 camelCase userIdorderList
常量 UPPER_SNAKE_CASE MAX_RETRY_COUNTDEFAULT_PAGE_SIZE
包名 全小写dot分隔 com.company.project.common.util

特定后缀/前缀

  • Service 接口:前缀 I,如 IUserService
  • Service 实现:后缀 Impl,如 UserServiceImpl
  • DTO后缀 DtoDTO
  • VO后缀 VO
  • 查询参数对象:后缀 QueryCriteria
  • 校验工具类:后缀 CheckerValidator
  • Manager后缀 Manager(复杂业务编排层)

3. 代码格式

  • 缩进4空格禁止Tab
  • 行长度最大120-200字符
  • 花括号K&R风格同一行开括号
  • 文件最大行数通常不超过2000行
  • 方法最大行数通常不超过150-300行
  • 参数数量最多7-9个超出考虑封装为对象
  • if嵌套深度最多3-4层超出考虑提取方法

4. 注释规范

类级Javadoc

/**
 * 用户服务类
 *
 * <p>提供用户注册、登录、信息管理等核心功能</p>
 *
 * @author authorName
 * @since 2024-01-01
 */

方法级Javadoc

/**
 * 根据用户ID获取用户信息
 *
 * @param userId 用户ID
 * @return 用户信息不存在返回null
 * @author authorName
 * @since 2024年1月1日 00:00:00
 */
public User getUserById(String userId) { }

字段注释

/** 用户ID */
private String userId;

行内注释

  • 注释放在代码上方或行尾
  • 复杂业务逻辑需注释说明

5. 异常处理

异常使用原则

  • 业务异常使用自定义异常(如 BusinessException
  • 参数校验异常使用 IllegalArgumentException 或专用校验异常
  • 系统异常使用 RuntimeException 包装

全局异常处理

@ControllerAdvice
@RestController
public class GlobalExceptionHandler {
    @ExceptionHandler(BusinessException.class)
    public Result<?> handleBusinessException(BusinessException e) {
        return Result.error(e.getCode(), e.getMessage());
    }
}

日志记录

log.info("用户登录成功userId={}", userId);
log.warn("订单处理超时orderId={}", orderId);
log.error("数据库连接失败", e);

6. 常用代码模式

DTO/Request/Response

@Data
@Accessors(chain = true)
public class UserDTO implements Serializable {
    @NotBlank(message = "用户名不能为空")
    private String username;

    @NotNull(message = "年龄不能为空")
    @Min(value = 0, message = "年龄不能为负数")
    private Integer age;
}

Entity

@Data
@Entity
@Table(name = "t_user")
public class User implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    private String id;

    @Column(name = "username")
    private String username;
}

Service

public interface IUserService {
    User getUserById(String userId);
}

@Service
@RequiredArgsConstructor
public class UserServiceImpl implements IUserService {
    private final IUserMapper userMapper;

    @Override
    public User getUserById(String userId) {
        return userMapper.selectById(userId);
    }
}

Controller

@RestController
@RequestMapping("/users")
@RequiredArgsConstructor
public class UserController {
    private final IUserService userService;

    @GetMapping("/{id}")
    public Result<User> getUserById(@PathVariable String id) {
        return Result.ok(userService.getUserById(id));
    }
}

校验工具

public class UserValidator {
    public static List<String> validate(UserDTO dto) {
        List<String> errors = new ArrayList<>();
        if (dto.getUsername() == null || dto.getUsername().isBlank()) {
            errors.add("用户名不能为空");
        }
        return errors;
    }
}

Enum

@Getter
@AllArgsConstructor
public enum UserStatus {
    ENABLE("启用", "enable"),
    DISABLE("禁用", "disable");

    private final String desc;
    private final String code;

    public static UserStatus getByCode(String code) {
        return Arrays.stream(values())
                .filter(e -> e.getCode().equals(code))
                .findFirst()
                .orElse(null);
    }
}

常量类

public interface UserConstants {
    int DEFAULT_PAGE_SIZE = 10;
    int MAX_PAGE_SIZE = 100;
    String DEFAULT_STATUS = "enable";
}

7. API设计规范

HTTP方法约束

强制约束:只能使用 GET 和 POST 方法

操作 方法 路径
查询 GET /users/{id}
列表 GET /users?name={name}
新增 POST /users
更新 POST + /update /users/update
删除 POST + /remove /users/remove
部分更新 POST + /patch /users/patch

说明:禁止使用 PUT、DELETE、PATCH 等其他HTTP方法。所有非GET请求均使用POST方法通过路径后缀区分操作类型。

统一响应格式

公司基础框架提供 RestResult<T> 统一响应格式:

return RestResult.ok(data);                                      // 成功
return RestResult.ok();                                           // 无返回值的成功
return RestResult.error(ResultCode.DATA_NONE);                    // 错误(根据错误码)
return RestResult.error(ResultCode.BUSINESS_LOGIC_ERROR, "自定义错误信息");

说明RestResult<T> 是公司基础框架的核心组件所有API响应必须使用该格式不可自行定义其他响应格式。

统一响应格式

public class RestResult<T> {
    private int code;
    private String message;
    private T data;

    public static <T> RestResult<T> ok(T data) { }
    public static <T> RestResult<T> error(String message) { }
    public static <T> RestResult<T> error(int code, String message) { }
}

8. 事务处理

@Transactional(rollbackFor = Exception.class)
public void saveUser(User user) {
    userMapper.insert(user);
    // 其他操作
}

9. API文档注解

Swagger/OpenAPI 3.0

@Api(tags = "用户管理")
@RestController
@RequestMapping("/users")
public class UserController {
    @ApiOperation("根据ID获取用户")
    @GetMapping("/{id}")
    public RestResult<User> getUser(@ApiParam("用户ID") @PathVariable String id) { }
}

SpringDoc OpenAPI推荐

@Tag(name = "用户管理", description = "用户相关接口")
@RestController
@RequestMapping("/users")
public class UserController {
    @Operation(summary = "根据ID获取用户")
    @GetMapping("/{id}")
    public RestResult<User> getUser(@Parameter(description = "用户ID") @PathVariable String id) { }
}

10. 禁止事项

  • 禁止魔法数字:使用常量替代,如 MAX_RETRY_COUNT
  • 禁止无用的import:保持代码整洁
  • 禁止长方法方法不超过150行拆分为多个小方法
  • 禁止深度嵌套if嵌套不超过3-4层
  • 禁止硬编码:配置信息放入配置文件
  • 禁止空指针:使用 Objects.requireNonNull() 或 Optional
  • 禁止swallow异常:异常必须记录或重新抛出

11. 最佳实践

  • 使用 Lombok 减少样板代码(@Data@Slf4j@Service
  • 使用 @RequiredArgsConstructor 代替构造器注入
  • 使用 Optional 处理可能为null的返回值
  • 使用 Stream API 处理集合操作
  • 接口方法参数不超过5个超出使用DTO封装
  • 日志记录使用占位符 {} 而非字符串拼接