Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有可变对象的不可变数组Java_Java_Immutability - Fatal编程技术网

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

具有可变对象的不可变数组Java,java,immutability,Java,Immutability,我有一个简单的类“a”,它是可变的 我希望使用可变对象“A”实现不可变列表,而不创建保证“A”类型对象不可变的类。这可能吗 public class App{ public class A{ int a; public A() {} public A(int a) { super(); this.a = a; } public int getA() {

我有一个简单的类“a”,它是可变的

我希望使用可变对象“A”实现不可变列表,而不创建保证“A”类型对象不可变的类。这可能吗

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
    }
}
公共类应用程序{
公共A类{
INTA;
公共A(){}
公共A(INTA){
超级();
这个a=a;
}
公共int getA(){
返回a;
}
公共无效setA(INTA){
这个a=a;
}
@凌驾
公共字符串toString(){
返回“A[A=“+A+”]”;
}
}
公共静态void main(字符串[]args)
{
App App=新App();
A A=应用程序新A(0);
ArrayList aList=新的ArrayList();
2.添加(a);
System.out.println(aList.toString());//结果是预期的0
a、 刚毛(99);
System.out.println(aList.toString());//结果是预期的99
ImmutableList ImmutableList=ImmutableList.copyOf(新的ArrayList(列表));
System.out.println(immutableList.toString());//结果与预期一致
a、 刚毛(50);
System.out.println(immutable.toString());//结果是50,我希望是99
}
}

我可能会让
A
实现一个接口(
I
),它公开必要的数据(通过getter),但不公开任何mutator方法

然后,在需要不可变列表/数组的地方,我会使用
I
而不是
A

这并不能保护你免受邪恶的投射或反射,但事实上,什么也不能保护你

请注意,如果不通过列表更改列表中的对象,则该更改将通过列表可见。所以这不是真正的不变性:

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
aa=新的A(1);
列表=新建LinkedList();
列表.添加(a);
System.out.println(list.get(0.getValue());//1.
a、 设定值(2);
System.out.println(list.get(0.getValue());//2.

对于true不可更改性,您必须将对象克隆到(比如)不可更改的
a
实例中,这些实例不公开设置器,也不维护到其原始对象的反向链接。

您必须对每个对象进行深度复制。看。并且可能会将其包装成一些可以阻止更改的东西。您可以将实现隐藏在一个不提供setter的接口后面。@rollback但是如果另一个类有一个实例没有隐藏在接口后面,那么该对象仍然会更改如何不可变?