不可变数组的修改不起作用

时间:2019-06-10 12:31:18

标签: java arrays immutability

修改了使数组不可变的代码,但是在某些地方出错了,就像在代码中一样,当为ImmutableClassWithArray创建对象时,列表是使用给定数组初始化的。在getter内部,返回不可修改的列表,并将其转换为数组。之后,将修改数组。即使在构造函数被调用之后,数组已经被更改,意味着在列表已经初始化了一些值之后,最终的数组仍然反映了更新后的值。

public final class ImmutableClassWithArray {

    private final Integer[] arr= {1,2,3,4};
    List<Integer> list;

    public ImmutableClassWithArray() {
        this.list = Collections.unmodifiableList(Arrays.asList(arr));
    }

    public Integer[] getArr() {
        return (Integer[]) this.list.toArray();   
    }

    public static void main(String[] args) {
        ImmutableClassWithArray ob = new ImmutableClassWithArray();
        System.out.println("list value after copying array "+ob.list.get(2));
        ob.arr[2]=5;        
        System.out.println("arr value after modified "+ob.arr[2]);

        Integer[] a = ob.getArr();
        System.out.println("a value -  "+a[2]);

    }
}

输出:->

复制数组3后的

列表值

修改5后的arr值

一个值-5

Integer [] a = ob.getArr();应该返回数组的原始值,因为列表在更改值之前已经初始化。 但是,就像在输出中获得“一个值-5”一样,它应该是“一个值-3”。

谢谢!!!!

2 个答案:

答案 0 :(得分:2)

请注意,不可修改不可变不同。

对不变的东西,您无能为力,无法修改其状态。

您无法通过该事物的界面通过不可修改的事物来修改其状态。但是,如果您可以通过其他方式访问数据,例如您可以直接访问支持数组,可以对其进行修改,并通过不可修改的列表来观察更改。

答案 1 :(得分:1)

制作数组final不会使其内容不变。只是说数组引用本身不能更改。

将其包装在unmodifiableList中仅意味着引用该List的人不能通过该List接口进行更新

但是,如果您可以访问数组(在执行操作时),您仍然可以更改其内容,并且无法修改的视图将相应地更新(它只是包装器,而不是副本)。

如果要保护数组的内容,则必须关闭对其的所有访问(将其设为私有,并且不允许对象的任何方法以任何方式更改其值。)

要注意的另一件事是,您在对阵列进行更新后正在执行Integer[] a = ob.getArr();。因此,使用toArray()从不可修改列表创建的新数组实例实际上反映了更新后的值。