本文目录导读:

我来提供一个全面的Java代码规范案例,包含实际代码示例和规范说明。
基础规范示例
package com.example.user.service;
import com.example.common.exception.BusinessException;
import com.example.user.dto.UserDTO;
import com.example.user.entity.User;
import com.example.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
/**
* 用户服务实现类
*
* @author Zhang San
* @since 1.0.0
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
/** 最大用户名长度 */
private static final int MAX_USERNAME_LENGTH = 50;
/** 默认分页大小 */
private static final int DEFAULT_PAGE_SIZE = 20;
private final UserRepository userRepository;
/**
* 根据ID查询用户
*
* @param userId 用户ID(必须大于0)
* @return 用户信息,不存在时返回null
* @throws IllegalArgumentException 当用户ID无效时
*/
@Override
@Transactional(readOnly = true)
public UserDTO getUserById(Long userId) {
// 参数校验
if (userId == null || userId <= 0) {
throw new IllegalArgumentException("用户ID必须大于0");
}
log.debug("查询用户信息,用户ID:{}", userId);
Optional<User> userOptional = userRepository.findById(userId);
return userOptional.map(this::convertToDTO)
.orElseGet(() -> {
log.warn("用户不存在,用户ID:{}", userId);
return null;
});
}
/**
* 创建新用户
*
* @param createRequest 创建请求(不能为null)
* @return 创建后的用户信息
* @throws BusinessException 当用户名已存在时
*/
@Override
@Transactional(rollbackFor = Exception.class)
public UserDTO createUser(UserCreateRequest createRequest) {
// 入参校验
validateCreateRequest(createRequest);
// 检查用户名唯一性
checkUsernameUnique(createRequest.getUsername());
// 构建实体
User user = new User();
user.setUsername(createRequest.getUsername());
user.setEmail(createRequest.getEmail());
user.setPasswordHash(encryptPassword(createRequest.getPassword()));
user.setStatus(UserStatus.ACTIVE);
user.setCreatedAt(LocalDateTime.now());
user.setUpdatedAt(LocalDateTime.now());
// 保存
User savedUser = userRepository.save(user);
log.info("用户创建成功,用户ID:{},用户名:{}", savedUser.getId(), savedUser.getUsername());
return convertToDTO(savedUser);
}
/**
* 查询用户列表
*
* @param pageNum 页码(从0开始)
* @param pageSize 分页大小(1-100)
* @return 用户列表
*/
@Override
@Transactional(readOnly = true)
public List<UserDTO> listUsers(int pageNum, int pageSize) {
// 参数校验
if (pageNum < 0) {
pageNum = 0;
}
if (pageSize < 1 || pageSize > 100) {
pageSize = DEFAULT_PAGE_SIZE;
}
List<User> users = userRepository.findByStatusOrderByCreatedAtDesc(
UserStatus.ACTIVE,
PageRequest.of(pageNum, pageSize)
);
return users.stream()
.map(this::convertToDTO)
.collect(Collectors.toList());
}
/**
* 校验创建请求
*
* @param request 创建请求
* @throws IllegalArgumentException 当参数不合法时
*/
private void validateCreateRequest(UserCreateRequest request) {
if (request == null) {
throw new IllegalArgumentException("创建请求不能为空");
}
if (!StringUtils.hasText(request.getUsername())) {
throw new IllegalArgumentException("用户名不能为空");
}
if (request.getUsername().length() > MAX_USERNAME_LENGTH) {
throw new IllegalArgumentException(
String.format("用户名长度不能超过%d个字符", MAX_USERNAME_LENGTH));
}
if (!StringUtils.hasText(request.getPassword()) ||
request.getPassword().length() < 8) {
throw new IllegalArgumentException("密码长度不能少于8个字符");
}
}
/**
* 校验用户名唯一性
*
* @param username 用户名
* @throws BusinessException 当用户名已存在时
*/
private void checkUsernameUnique(String username) {
boolean exists = userRepository.existsByUsername(username);
if (exists) {
throw new BusinessException("用户名已存在:" + username);
}
}
/**
* 将实体转换为DTO
*
* @param user 用户实体
* @return 用户DTO
*/
private UserDTO convertToDTO(User user) {
if (user == null) {
return null;
}
UserDTO dto = new UserDTO();
dto.setId(user.getId());
dto.setUsername(user.getUsername());
dto.setEmail(user.getEmail());
dto.setStatus(user.getStatus());
dto.setCreatedAt(user.getCreatedAt());
dto.setLastLoginAt(user.getLastLoginAt());
return dto;
}
/**
* 加密密码
*
* @param rawPassword 原始密码
* @return 加密后的密码
*/
private String encryptPassword(String rawPassword) {
// 实际项目中应使用BCrypt等加密算法
return "encrypted_" + rawPassword.hashCode();
}
}
实体类规范
package com.example.user.entity;
import jakarta.persistence.*;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 用户实体类
*
* @author Zhang San
* @since 1.0.0
*/
@Data
@Entity
@Table(name = "t_user",
indexes = {
@Index(name = "idx_username", columnList = "username"),
@Index(name = "idx_email", columnList = "email")
})
public class User {
/** 主键ID */
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/** 用户名 */
@Column(nullable = false, length = 50, unique = true)
private String username;
/** 邮箱 */
@Column(nullable = false, length = 100, unique = true)
private String email;
/** 密码哈希 */
@Column(name = "password_hash", nullable = false, length = 255)
private String passwordHash;
/** 用户状态 */
@Enumerated(EnumType.STRING)
@Column(nullable = false, length = 20)
private UserStatus status;
/** 创建时间 */
@Column(name = "created_at", nullable = false, updatable = false)
private LocalDateTime createdAt;
/** 更新时间 */
@Column(name = "updated_at", nullable = false)
private LocalDateTime updatedAt;
/** 最后登录时间 */
@Column(name = "last_login_at")
private LocalDateTime lastLoginAt;
}
异常处理规范
package com.example.common.exception;
/**
* 业务异常基类
*
* @author Zhang San
* @since 1.0.0
*/
public class BusinessException extends RuntimeException {
private static final long serialVersionUID = 1L;
/** 错误码 */
private final String errorCode;
/** 错误详情 */
private final Object[] params;
public BusinessException(String message) {
this("BUSINESS_ERROR", message, null);
}
public BusinessException(String errorCode, String message, Object[] params) {
super(message);
this.errorCode = errorCode;
this.params = params;
}
public String getErrorCode() {
return errorCode;
}
public Object[] getParams() {
return params;
}
}
工具类规范
package com.example.common.util;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 集合工具类
*
* @author Zhang San
* @since 1.0.0
*/
public final class CollectionUtils {
private CollectionUtils() {
// 私有构造器,防止实例化
}
/**
* 判断集合是否为空
*
* @param collection 集合
* @return 为空返回true
*/
public static boolean isEmpty(Collection<?> collection) {
return collection == null || collection.isEmpty();
}
/**
* 判断集合是否不为空
*
* @param collection 集合
* @return 不为空返回true
*/
public static boolean isNotEmpty(Collection<?> collection) {
return !isEmpty(collection);
}
/**
* 获取第一个元素,空集合返回null
*
* @param collection 集合
* @param <T> 元素类型
* @return 第一个元素或null
*/
public static <T> T getFirst(Collection<T> collection) {
if (isEmpty(collection)) {
return null;
}
return collection.iterator().next();
}
/**
* 安全的转换列表
*
* @param source 源集合
* @param mapper 转换函数
* @param <S> 源类型
* @param <T> 目标类型
* @return 转换后的列表
*/
public static <S, T> List<T> safeMap(Collection<S> source,
java.util.function.Function<S, T> mapper) {
if (isEmpty(source)) {
return Collections.emptyList();
}
return source.stream()
.filter(Objects::nonNull)
.map(mapper)
.collect(Collectors.toList());
}
}
控制器规范
package com.example.user.controller;
import com.example.common.response.ApiResponse;
import com.example.user.dto.UserDTO;
import com.example.user.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Positive;
import java.util.List;
/**
* 用户控制器
*
* @author Zhang San
* @since 1.0.0
*/
@Slf4j
@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
/**
* 获取用户详情
*
* @param userId 用户ID
* @return 用户信息
*/
@GetMapping("/{userId}")
public ApiResponse<UserDTO> getUserById(
@PathVariable @Positive(message = "用户ID必须为正数") Long userId) {
log.debug("请求获取用户详情,用户ID:{}", userId);
UserDTO user = userService.getUserById(userId);
return ApiResponse.success(user);
}
/**
* 创建用户
*
* @param request 创建请求
* @return 创建的用户信息
*/
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public ApiResponse<UserDTO> createUser(@Valid @RequestBody UserCreateRequest request) {
log.debug("请求创建用户,用户名:{}", request.getUsername());
UserDTO createdUser = userService.createUser(request);
return ApiResponse.success("创建成功", createdUser);
}
/**
* 获取用户列表
*
* @param pageNum 页码
* @param pageSize 每页大小
* @return 用户列表
*/
@GetMapping
public ApiResponse<List<UserDTO>> listUsers(
@RequestParam(defaultValue = "0") int pageNum,
@RequestParam(defaultValue = "20") int pageSize) {
log.debug("请求获取用户列表,页数:{},每页:{}", pageNum, pageSize);
List<UserDTO> users = userService.listUsers(pageNum, pageSize);
return ApiResponse.success(users);
}
}
配置文件规范示例
# application.yml
spring:
application:
name: user-service
datasource:
url: jdbc:mysql://localhost:3306/user_db?useSSL=false&characterEncoding=utf8
username: ${DB_USERNAME:root}
password: ${DB_PASSWORD:password}
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: validate
show-sql: false
properties:
hibernate:
format_sql: true
dialect: org.hibernate.dialect.MySQLDialect
# 自定义配置
app:
security:
jwt-secret: ${JWT_SECRET:change-me-in-production}
token-expiration-hours: 24
logging:
enabled: true
level: INFO
测试规范示例
package com.example.user.service;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
/**
* 用户服务测试类
*
* @author Zhang San
* @since 1.0.0
*/
@ExtendWith(MockitoExtension.class)
@DisplayName("UserService单元测试")
class UserServiceImplTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserServiceImpl userService;
private User mockUser;
@BeforeEach
void setUp() {
mockUser = new User();
mockUser.setId(1L);
mockUser.setUsername("test_user");
mockUser.setEmail("test@example.com");
mockUser.setStatus(UserStatus.ACTIVE);
}
@Test
@DisplayName("根据ID查询用户成功时返回用户信息")
void getUserById_success_shouldReturnUser() {
// given
when(userRepository.findById(1L)).thenReturn(Optional.of(mockUser));
// when
UserDTO result = userService.getUserById(1L);
// then
assertThat(result).isNotNull();
assertThat(result.getId()).isEqualTo(1L);
assertThat(result.getUsername()).isEqualTo("test_user");
}
@Test
@DisplayName("用户ID无效时抛出异常")
void getUserById_invalidId_shouldThrowException() {
// given
Long invalidId = -1L;
// when & then
assertThatThrownBy(() -> userService.getUserById(invalidId))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("用户ID必须大于0");
}
@Test
@DisplayName("创建用户时用户名已存在应抛出业务异常")
void createUser_duplicateUsername_shouldThrowBusinessException() {
// given
UserCreateRequest request = new UserCreateRequest();
request.setUsername("existing_user");
request.setPassword("password123");
request.setEmail("test@example.com");
when(userRepository.existsByUsername("existing_user")).thenReturn(true);
// when & then
assertThatThrownBy(() -> userService.createUser(request))
.isInstanceOf(BusinessException.class)
.hasMessageContaining("用户名已存在");
}
@Test
@DisplayName("用户名空值时抛出IllegalArgumentException")
void createUser_emptyUsername_shouldThrowException() {
// given
UserCreateRequest request = new UserCreateRequest();
request.setUsername("");
request.setPassword("password123");
// when & then
assertThatThrownBy(() -> userService.createUser(request))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("用户名不能为空");
}
@Test
@DisplayName("密码过短时抛出IllegalArgumentException")
void createUser_shortPassword_shouldThrowException() {
// given
UserCreateRequest request = new UserCreateRequest();
request.setUsername("test_user");
request.setPassword("short");
// when & then
assertThatThrownBy(() -> userService.createUser(request))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("密码长度不能少于8个字符");
}
}
最佳实践总结
命名规范
// 类名:UpperCamelCase
public class UserService {}
// 方法名/变量名:lowerCamelCase
public UserDTO getUserById(Long userId) {}
private final UserRepository userRepository;
// 常量:UPPER_SNAKE_CASE
private static final int MAX_RETRY_COUNT = 3;
// 包名:小写字母
package com.example.user.service;
注释规范
/**
* 类级别的Javadoc
*
* @author 作者
* @since 版本
*/
public class UserService {}
/**
* 方法级别的Javadoc
*
* @param userId 参数说明
* @return 返回值说明
* @throws 异常说明
*/
public UserDTO getUserById(Long userId) {}
代码组织
public class UserServiceImpl {
// 1. 静态常量
private static final MAX_PAGE_SIZE = 100;
// 2. 实例变量
private final UserRepository userRepository;
// 3. 公共方法
public UserDTO getUserById(Long userId) {}
// 4. 私有辅助方法
private void validateRequest(UserCreateRequest request) {}
// 5. 重写的equals/hashCode/toString
// 如果必要
}
这份Java代码规范涵盖了命名、格式、注释、异常处理、测试等方面,是实际企业中常用的规范标准,通过遵循这些规范,可以有效提高代码的可读性、可维护性和团队协作效率。