尽管有一个可变成员,我怎么能让这个类不可变?

use*_*108 4 java list immutability

我想使下面的类不可变,即使它有一个可变的List成员.我怎样才能做到这一点?

class MyImmutableClass {
        private List<Integer> data;
        public MyImmutableClass(List<Integer> data) {
            this.data = data;
        }
        public List<Integer> getData() {
            return data;
        }
    }
Run Code Online (Sandbox Code Playgroud)

下面是测试类,它的main()函数修改了对象状态.

class TestMyImmutableClass{
    public static void main(String[] args) {
        List<Integer> data = new ArrayList<Integer>();
        data.add(2);
        data.add(5);
        MyImmutableClass obj = new MyImmutableClass(data);
        obj.getData().add(3);
        System.out.println("Data is; " + obj.getData());
    }
}
Run Code Online (Sandbox Code Playgroud)

O/P: Data is; [2, 5, 3]

Mad*_*mer 7

在你的getData方法中,而不是返回你的List喜欢的引用...

public List<Integer> getData() {
    return data;
}
Run Code Online (Sandbox Code Playgroud)

你可以返回一个不可修改的List,而不是

public List<Integer> getData() {
    return Collections.unmodifiableList(data);
}
Run Code Online (Sandbox Code Playgroud)

查看Collections.unmodifiableList更多详情......

更新

正如user949300所指出的,您还应该复制原始列表.

public MyImmutableClass(List<Integer> data) {
    this.data = new ArrayList<Integer>(data);
}
Run Code Online (Sandbox Code Playgroud)

这将阻止任何有权访问原始列表的人对其进行修改.

  • 这是Guava`ImputableList`的一个很好的用例. (3认同)

use*_*300 6

在你的构造函数中,去吧

this.data = Collections.unmodifiableList(new ArrayList(data));

为了完整性和清晰度,将数据字段声明为final.