繁体   English   中英

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

[英]How can I make this class immutable despite having a mutable member?

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

class MyImmutableClass {
        private List<Integer> data;
        public MyImmutableClass(List<Integer> data) {
            this.data = data;
        }
        public List<Integer> getData() {
            return data;
        }
    }

下面是测试类,其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());
    }
}

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

getData方法中,而不是返回对List的引用,如...

public List<Integer> getData() {
    return data;
}

您可以返回不可修改的List

public List<Integer> getData() {
    return Collections.unmodifiableList(data);
}

有关详细信息,请参阅Collections.unmodifiableList ...

更新

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

public MyImmutableClass(List<Integer> data) {
    this.data = new ArrayList<Integer>(data);
}

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

在你的构造函数中,去吧

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

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

如果您正在使用Eclipse Collections ,则可以将MyImmutableClass.data的类型MyImmutableClass.dataImmutableList

class MyImmutableClass {
    private ImmutableList<Integer> data;
    public MyImmutableClass(List<Integer> data) {
        this.data = Lists.immutable.withAll(data);
    }
    public ListIterable<Integer> getData() {
        return data;
    }
}

Eclipse Collection的ImmutableListListIterable类型是契约不可变的,这意味着它们没有add()remove()方法。 这样,从getData()的返回类型可以清楚地看出,返回的列表无法更改。

无论ImmutableListMutableList延长ListIterable ,所以你可以从一个实施改变ImmutableList一个不可修改的列表而不改变API。

class MyImmutableClass {
    private MutableList<Integer> data;
    public MyImmutableClass(List<Integer> data) {
        this.data = Lists.mutable.withAll(data);
    }
    public ListIterable<Integer> getData() {
        return data.asUnmodifiable();
    }
}

注意:我是Eclipse集合的提交者。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM