final public class ImmutableWithObject {
final Object obj;
final List myList;
ImmutableWithObject(Object obj1, List list)
{
this.obj = obj1;
this.myList = ((List) ((ArrayList) list).clone());
}
public Object getObj() {
return this.obj;
}
public List getMyList() {
return (List) ((ArrayList<String>) this.myList).clone();
}
public static void main(String[] args) {
ImmutableWithObject io = new ImmutableWithObject(new Date(), new ArrayList());
((Date) io.getObj()).setDate(22);
System.out.println((Date) io.getObj());
}
}
o/p : Mon Aug 22 00:50:04 IST 2011
这是不正确的。
答案 0 :(得分:6)
不可变意味着一旦构造了对象,其状态就不会改变。
来自EJ第15项&lt; - 更多信息
除非有充分的理由让它们变得可变,否则类应该是不可变的。如果一个类不能成为不可变的,尽可能地限制它的可变性。
答案 1 :(得分:2)
您不能使其不可变,因为此对象无法创建列表或Object的内容的副本。假设您想要访问这些属性的getter,属性本身是在别处创建的,并且可以在此类的外部代码中更改,该类具有对它的引用。
唯一的例外是Object和List的内容本身是不可变的。然后,您可以创建列表的不可变副本,您将完成。
答案 2 :(得分:1)
您可以复制List对象的值。无论谁调用它仍然具有该列表并且可以修改它。
答案 3 :(得分:0)
将成员变量设为private final并复制参数:
final class ImmutableWithObject {
private final Object obj;
private final List myList;
public ImmutableWithObject(Object obj1 , List list)
{
this.obj = obj1.clone();
this.list = (List) list.clone();
}
}
这不允许任何其他类更改您的内部状态,也不允许ImmutableWithobject更改myList
或obj
引用。 然而 obj的状态以及列表仍然可以在内部操作。正如其他人所指出的那样,无论谁通过名单或obj1到你的班级,也能够从外部操纵它。由于在C ++中没有类似const
的东西,我们必须复制对象以确保它们不会从外部更改。
同样,如果有一个getter,它也应该只返回一个副本(或一些只读接口或只读包装器):
public Object getObj() { return obj.clone(); }