Java 语言规范

名称

Java 语言规范

分类

rules

路径

rules/java.mdc

描述

该规则解释了 Java 的约定和最佳实践。

Java 语言规范

Java 21 特性使用

  • Record类:用于不可变数据传输对象

    public record UserInfo(String name, String email, LocalDateTime createdAt) {}
    
  • Pattern Matching:在switch表达式中使用模式匹配

    public String formatValue(Object value) {
        return switch (value) {
            case String s -> "String: " + s;
            case Integer i -> "Number: " + i;
            case null -> "null value";
            default -> "Unknown: " + value.toString();
        };
    }
    
  • Text Blocks:用于多行字符串,特别是SQL和JSON

    String sql = """
        SELECT u.name, u.email
        FROM users u
        WHERE u.status = 'ACTIVE'
        ORDER BY u.created_at DESC
        """;
    
  • Sealed Classes:用于受限的类层次结构

    public sealed class Result<T> permits Success, Error {
        // 基类定义
    }
    
    public final class Success<T> extends Result<T> {
        private final T data;
        // 实现
    }
    
  • Virtual Threads:用于高并发场景

    try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
        executor.submit(() -> {
            // 高并发任务
        });
    }
    

命名约定

  • 类名:使用帕斯卡命名法(如 UserControllerOrderService
  • 方法和变量名:使用驼峰命名法(如 findUserByIdisOrderValid
  • 常量:使用全大写下划线分隔(如 MAX_RETRY_ATTEMPTSDEFAULT_PAGE_SIZE
  • 包名:使用小写,按功能模块划分(如 com.example.user.domain

代码风格

  • 缩进:使用4个空格,不使用Tab
  • 行长度:每行不超过120个字符
  • 大括号:使用Egyptian风格(开括号不换行)
  • 空行:方法间使用一个空行分隔,逻辑块间使用空行分隔

异常处理

  • 检查异常:谨慎使用检查异常,优先使用运行时异常

  • 异常链:保持异常链,不丢失原始异常信息

    try {
        // 可能抛出异常的代码
    } catch (SpecificException e) {
        throw new BusinessException("业务处理失败", e);
    }
    
  • 资源管理:使用try-with-resources自动管理资源

    try (var reader = Files.newBufferedReader(path)) {
        // 使用reader
    }
    

集合和流处理

  • 集合选择:根据使用场景选择合适的集合类型

    • ArrayList:随机访问频繁
    • LinkedList:插入删除频繁
    • HashMap:键值对存储
    • TreeMap:需要排序的键值对
  • Stream API:充分利用Stream API进行函数式编程

    List<String> activeUserNames = users.stream()
        .filter(user -> user.isActive())
        .map(User::getName)
        .sorted()
        .toList();
    

并发编程

  • 线程安全:优先使用不可变对象和线程安全的集合
  • 锁机制:合理使用synchronized、ReentrantLock等锁机制
  • 并发集合:使用ConcurrentHashMap、CopyOnWriteArrayList等并发集合
  • CompletableFuture:使用CompletableFuture处理异步操作
    CompletableFuture<String> future = CompletableFuture
        .supplyAsync(() -> fetchData())
        .thenApply(data -> processData(data))
        .exceptionally(throwable -> "默认值");
    

内存管理

  • 对象创建:避免在循环中创建不必要的对象
  • 字符串处理:大量字符串操作使用StringBuilder
  • 集合大小:预估集合大小,避免频繁扩容
  • 弱引用:适当使用WeakReference避免内存泄漏

泛型使用

  • 类型安全:充分利用泛型提供类型安全
  • 通配符:正确使用上界通配符(? extends)和下界通配符(? super)
  • 类型擦除:理解泛型类型擦除的限制
    public <T extends Comparable<T>> T findMax(List<T> list) {
        return list.stream().max(Comparable::compareTo).orElse(null);
    }
    

注解使用

  • 标准注解:正确使用@Override、@Deprecated、@SuppressWarnings等
  • 自定义注解:合理创建自定义注解简化代码
  • 注解处理:了解编译时和运行时注解处理

测试规范

  • 单元测试:使用JUnit 5编写单元测试
  • 测试命名:测试方法使用描述性命名(如 shouldReturnUserWhenValidIdProvided
  • 断言:使用AssertJ提供更好的断言体验
    @Test
    void shouldCalculateCorrectTotal() {
        // Given
        List<Item> items = List.of(
            new Item("item1", 10.0),
            new Item("item2", 20.0)
        );
    
        // When
        double total = calculator.calculateTotal(items);
    
        // Then
        assertThat(total).isEqualTo(30.0);
    }
    

性能优化

  • 算法复杂度:选择合适的算法和数据结构
  • 缓存策略:合理使用缓存减少重复计算
  • 懒加载:对于昂贵的操作使用懒加载
  • 批量处理:批量处理数据库操作和网络请求

代码质量

  • 单一职责:每个类和方法只负责一个功能
  • 开闭原则:对扩展开放,对修改关闭
  • 依赖倒置:依赖抽象而不是具体实现
  • 接口隔离:使用小而专一的接口
  • 代码复用:提取公共逻辑,避免重复代码

文档和注释

  • JavaDoc:为公共API编写完整的JavaDoc
  • 代码注释:为复杂逻辑添加解释性注释
  • TODO标记:使用TODO标记待完成的工作
    /**
     * 计算用户积分
     *
     * @param userId 用户ID
     * @param actions 用户行为列表
     * @return 计算得出的积分值
     * @throws UserNotFoundException 当用户不存在时抛出
     */
    public int calculatePoints(Long userId, List<UserAction> actions) {
        // TODO: 实现积分计算逻辑
        return 0;
    }