简体   繁体   English

具有可变对象Java的不可变数组

[英]Immutable Array with Mutable Objects Java

I have a simple class "A", which is mutable. 我有一个简单的类“A”,这是可变的。

I would like to achieve immutable list using mutable objects "A" without creating class that guarantees immutability for objects of type "A". 我想使用可变对象“A”来实现不可变列表,而不创建保证类型为“A”的对象不变的类。 Is this possible? 这可能吗?

public class App{
    public class A{
        int a;

        public A() {}

        public A(int a) {
            super();
            this.a = a;
        }

        public int getA() {
            return a;
        }

        public void setA(int a) {
            this.a = a;
        }

        @Override
        public String toString() {
            return "A [a=" + a + "]";
        }

    }

    public static void main( String[] args )
    {
        App app = new App();
        A a = app.new A(0);
        ArrayList<A> aList = new ArrayList<A>();
        aList.add(a);
        System.out.println(aList.toString());//result is 0 as expected
        a.setA(99);
        System.out.println(aList.toString());//result is 99 as expected
        ImmutableList<A> immutableList = ImmutableList.copyOf(new ArrayList<A>(aList));
        System.out.println(immutableList.toString());//result is 99 as expected
        a.setA(50);
        System.out.println(immutable.toString());//result is 50 and I was expecting 99
    }
}

I would probably make A implement an interface ( I ) which exposes the necessary data (via getters) but doesn't expose any mutator methods. 我可能会使A实现一个接口( I ),它暴露必要的数据(通过getter),但暴露任何mutator方法。

Then, where I needed the immutable list/array, I'd use I rather than A . 然后,在我需要不可变列表/数组的地方,我使用的是I而不是A

This doesn't protect you from nefarious casts or reflection, but then, virtually nothing does. 这并不能保护你免受邪恶的演员阵容或反射,但是,实际上什么也没有。

Note that if you change an object that's in the list not via the list, that change will be visible via the list. 请注意,如果您更改列表中不在列表中的对象,则该更改将通过列表显示。 So it's not true immutability: 所以这不是真正的不变性:

A a = new A(1);
List<I> list = new LinkedList<>();
list.add(a);
System.out.println(list.get(0).getValue()); // 1
a.setValue(2);
System.out.println(list.get(0).getValue()); // 2

For true immutability, you'll have to clone the objects into (say) ImmutableA instances that expose no setters and maintain no backward link to their original object. 为了实现真正的不变性,您必须将对象克隆到(比如说) ImmutableA实例中,这些实例不会暴露任何setter并且不会保持与其原始对象的反向链接。

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

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