使用防御性复制创建类型的不可变版本

Java 中的一些基本类型和类从根本上是可变的。例如,所有数组类型都是可变的,像 java.util.Data 这样的类也是如此。在强制要求不可变类型的情况下,这可能很尴尬。

解决这个问题的一种方法是为可变类型创建一个不可变的包装器。这是一个整数数组的简单包装器

public class ImmutableIntArray {
    private final int[] array;
    
    public ImmutableIntArray(int[] array) {
        this.array = array.clone();
    }

    public int[] getValue() {
        return this.clone();
    }
}

这个类通过使用防御性复制来将可变状态(int[])与可能使其变异的任何代码隔离开来:

  • 构造函数使用 clone() 创建参数数组的不同副本。如果构造函数的调用者随后更改了参数数组,则不会影响 ImmutableIntArray 的状态。

  • getValue() 方法还使用 clone() 来创建返回的数组。如果调用者要更改结果数组,则不会影响 ImmutableIntArray 的状态。

我们还可以向 ImmutableIntArray 添加方法,以对包装数组执行只读操作; 例如,获取其长度,获取特定索引处的值,等等。

请注意,以这种方式实现的不可变包装类型与原始类型不兼容。你不能简单地用前者代替后者。