具有可变对象的不可变数组 Java
Immutable Array with Mutable Objects Java
我有一个简单的 class "A",它是可变的。
我想使用可变对象 "A" 实现不可变列表,而不创建 class 来保证 "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
实现一个接口 (I
) 公开必要的数据(通过 getters)但是 不 公开任何修改器方法。
然后,在我需要不可变 list/array 的地方,我会使用 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
对于 true 不变性,您必须将对象克隆到(比如)ImmutableA
不暴露 setter 且不保持向后的实例 link到他们原来的对象。
我有一个简单的 class "A",它是可变的。
我想使用可变对象 "A" 实现不可变列表,而不创建 class 来保证 "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
实现一个接口 (I
) 公开必要的数据(通过 getters)但是 不 公开任何修改器方法。
然后,在我需要不可变 list/array 的地方,我会使用 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
对于 true 不变性,您必须将对象克隆到(比如)ImmutableA
不暴露 setter 且不保持向后的实例 link到他们原来的对象。