You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lombok @Value注解构建不可变Java类失效问题咨询

问题原因

Lombok的@Value注解默认对数组类型生成的getter方法,会直接返回数组的原始引用,而非创建并返回拷贝。这就导致外部调用getTags()拿到数组后,能直接修改数组元素,进而改变实例内部的状态,违背了不可变类的设计初衷。

解决方案

1. 手动重写数组getter,返回拷贝

直接覆盖默认生成的getter方法,每次调用时返回数组的拷贝,这样外部修改的只是拷贝,不会影响原实例的内部数组:

import lombok.Value;

@Value
public class ValueExample {
    String[] tags;

    public String[] getTags() {
        return tags.clone();
    }
}

2. 禁用Lombok默认getter后自定义

如果不想完全覆盖@Value的生成逻辑,可以先让Lombok不生成默认的数组getter,再自行实现安全的版本:

import lombok.Getter;
import lombok.Value;
import lombok.AccessLevel;

@Value
public class ValueExample {
    @Getter(AccessLevel.NONE)
    String[] tags;

    public String[] getTags() {
        return tags.clone();
    }
}

3. 替换数组为不可变集合(推荐)

从根源避免数组可变的问题,将数组替换为不可变集合类型,比如Java 9+的List.of()、Guava的ImmutableList:

import lombok.Value;
import java.util.List;

@Value
public class ValueExample {
    List<String> tags;

    // 从数组初始化时转为不可变List
    public ValueExample(String[] tags) {
        this.tags = List.of(tags); // 返回不可变List,外部无法修改元素
        // 若使用Guava:this.tags = ImmutableList.copyOf(tags);
    }
}

这种方式下,外部获取的List本身就是不可变的,彻底保证了实例的不可变性。

补充说明

@Value注解在处理数组、普通集合这类可变引用类型时,不会自动做深拷贝或包装为不可变类型——这是开发者需要自行处理的细节,毕竟不可变类的核心要求是所有内部状态无法被外部修改,而数组本身是可变对象,直接暴露引用必然会破坏不可变性。

内容的提问来源于stack exchange,提问作者Gep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 20:22:12