java Records 怎么使用

Java Records 是 Java 14 引入、Java 16 正式化的特性,用于创建不可变的数据载体类。下面详细说明使用方法:

1. 基本语法

java 复制代码
public record Point(int x, int y) {}

编译器会自动生成:

  • 私有 final 字段(x, y
  • 规范构造函数
  • 访问器方法(x(), y()
  • equals(), hashCode(), toString()

2. 自定义构造函数

紧凑构造函数(推荐)

java 复制代码
public record Point(int x, int y) {
    public Point {
        // 参数验证
        if (x < 0 || y < 0) {
            throw new IllegalArgumentException("坐标不能为负数");
        }
        // 无需显式赋值,编译器自动处理
    }
}

传统构造函数

java 复制代码
public record Point(int x, int y) {
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

3. 添加方法

java 复制代码
public record Point(int x, int y) {
    // 实例方法
    public double distanceTo(Point other) {
        int dx = x - other.x;
        int dy = y - other.y;
        return Math.sqrt(dx * dx + dy * dy);
    }
    
    // 静态方法
    public static Point origin() {
        return new Point(0, 0);
    }
}

4. 实际使用示例

java 复制代码
// 定义Record
public record User(
    Long id,
    String username,
    String email,
    LocalDateTime createdAt
) {
    public User {
        // 验证逻辑
        Objects.requireNonNull(username);
        Objects.requireNonNull(email);
        
        // 数据转换
        email = email.toLowerCase();
    }
    
    // 便捷构造函数
    public User(String username, String email) {
        this(null, username, email, LocalDateTime.now());
    }
}

// 使用
public class Main {
    public static void main(String[] args) {
        // 创建实例
        User user = new User(1L, "alice", "ALICE@EXAMPLE.COM", LocalDateTime.now());
        
        // 访问器方法(没有get前缀)
        System.out.println(user.username()); // "alice"
        System.out.println(user.email());    // "alice@example.com"
        
        // 自动生成的toString()
        System.out.println(user); 
        // 输出: User[id=1, username=alice, email=alice@example.com, ...]
        
        // 解构(Java 21+)
        if (user instanceof User(Long id, String name, String email, LocalDateTime time)) {
            System.out.println("ID: " + id);
        }
    }
}

5. 结合其他特性

与 Stream API 结合

java 复制代码
record Person(String name, int age) {}

List<Person> people = List.of(
    new Person("Alice", 25),
    new Person("Bob", 30)
);

// 过滤并获取名字
List<String> names = people.stream()
    .filter(p -> p.age() > 25)
    .map(Person::name)
    .toList();

作为 DTO 使用

java 复制代码
// API 响应
public record ApiResponse<T>(
    boolean success,
    String message,
    T data,
    LocalDateTime timestamp
) {}

// 在Spring Boot中作为返回类型
@RestController
public class UserController {
    @GetMapping("/users/{id}")
    public ApiResponse<User> getUser(@PathVariable Long id) {
        User user = userService.findById(id);
        return new ApiResponse<>(true, "成功", user, LocalDateTime.now());
    }
}

6. 重要注意事项

  1. Record 是 final 的,不能继承其他类

  2. 可以继承接口

    java 复制代码
    public record Person(String name, int age) implements Serializable, Comparable<Person> {
        @Override
        public int compareTo(Person other) {
            return this.name.compareTo(other.name);
        }
    }
  3. 可以有静态字段和方法

  4. 不能有实例字段(除自动生成的)

  5. 可以嵌套和泛型化

    java 复制代码
    public record Pair<T, U>(T first, U second) {}

7. 适用场景

✅ 适合使用:

  • DTO(数据传输对象)
  • 值对象(Value Objects)
  • 不可变数据容器
  • 方法返回多个值
  • 临时数据存储

❌ 不适合:

  • 需要可变状态
  • 需要继承其他类
  • 需要复杂的业务逻辑
  • 需要序列化特殊处理

8. Java 21+ 增强

java 复制代码
// 解构模式匹配
switch (obj) {
    case Point(int x, int y) -> System.out.printf("点(%d, %d)", x, y);
    case User(String name, int age) -> System.out.println(name);
    default -> {}
}

总结

Records 大大简化了数据载体的创建,减少了样板代码,增强了代码可读性和安全性。建议在以下情况优先使用 Record:

  1. 数据建模(DTO、VO)
  2. 方法返回多个值
  3. 需要值语义的简单类
  4. 不可变数据容器

但要注意,Record 不是所有场景的替代品,复杂的业务逻辑类仍然应该使用完整的类定义。

相关推荐
Gofarlic_OMS几秒前
装备制造企业Fluent许可证成本分点典型案例
java·大数据·开发语言·人工智能·自动化·制造
码王吴彦祖10 分钟前
顶象 AC 纯算法迁移实战:从补环境到纯算的完整拆解
java·前端·算法
开心码农1号1 小时前
Java rabbitMQ如何发送、消费消息、全套可靠方案
java·rabbitmq·java-rabbitmq
蜡台1 小时前
JetBrains IDEA 安装 卸载相关总结
java·ide·intellij-idea·注册码
WJLSH1231 小时前
TomCat
java·tomcat
戮戮2 小时前
Spring Cloud Gateway 零拷贝参数校验:一种高性能网关架构实践
java·网络·架构·gateway
alengan2 小时前
cocos自动编译-Android自动出apk包
java·eclipse
漫霂2 小时前
二叉树的统一迭代遍历
java·算法
文静小土豆2 小时前
K8s 滚动更新在 Java 应用中的实践与优化
java·容器·kubernetes
HSunR2 小时前
java springboot3 后端 基础框架
java·开发语言