Java代码规范案例

wen java案例 1

本文目录导读:

Java代码规范案例

  1. 基础规范示例
  2. 实体类规范
  3. 异常处理规范
  4. 工具类规范
  5. 控制器规范
  6. 配置文件规范示例
  7. 测试规范示例
  8. 最佳实践总结

我来提供一个全面的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代码规范涵盖了命名、格式、注释、异常处理、测试等方面,是实际企业中常用的规范标准,通过遵循这些规范,可以有效提高代码的可读性、可维护性和团队协作效率。

抱歉,评论功能暂时关闭!