Lombok 值注释对于不可变 java 类无法正常工作

问题描述 投票:0回答:1

我想看看是否可以使用 Lombok 创建一个不可变的 Java 类。我在 Lombok 网站上找到了这个页面“不可变类变得非常简单”,但我不相信它:https://projectlombok.org/features/Value

我已经使用他们在该页面中使用的示例类对其进行了测试,即

@Value
public class ValueExample {
  String name;
  @With(AccessLevel.PACKAGE) @NonFinal int age;
  double score;
  protected String[] tags;
  
  @ToString(includeFieldNames=true)
  @Value(staticConstructor="of")
  public static class Exercise<T> {
    String name;
    T value;
  }
}

并写了一个小测试:

public static void main(String... args) {

    String tags[] = {"a", "b", "c"};

    ValueExample t = new ValueExample("name", 1, 2.3, tags);

    System.out.println("BEFORE:" + Arrays.toString(t.getTags()));

    String[] tagsToModify = t.getTags();

    for (int i = 0; i < tags.length; i++) {
        tagsToModify[i] = "?";
    }

    System.out.println("AFTER: " + Arrays.toString(t.getTags()));
}

测试的输出是:

BEFORE:[a, b, c]
AFTER: [?, ?, ?]

对我来说这意味着类不是一成不变的。 我错过了一些明显的东西吗?

java immutability lombok
1个回答
2
投票

问题是

tags
是一个
Array
,因此是一个引用类型,而数组是可变的。虽然您确实无法更改
tags
的值(例如,您无法将其重新分配以引用不同的数组),但它引用的数组可以由持有对它的引用的任何人(包括
ValueExample
类本身,或您创建的用于测试此行为的
main
方法)。

暂时将反射放在一边(因为它提供了一个破坏不变性的“后门”),对于一个真正不可变的类,所有引用的属性也应该是不可变的 - 而 Array 不是 - 或者你可能不得不求助于防御性复制等技术

© www.soinside.com 2019 - 2024. All rights reserved.