有人可以告诉我们如何阻止用户修改不可变类中定义的可变对象的值吗?
示例:
我们有一个不可变的Student
类,它包含Address
类的最终引用,它是可变的。我想阻止用户在Address
类中进行任何更改?
答案 0 :(得分:1)
安排Address
成为interface
。像往常一样使你的可变MutableAddress
成为一个ImmutableAddress
包装它,防止对字段的写访问。
interface Address {
public String getNumber();
public void setNumber(String number) throws IllegalAccessException;
public String getStreet();
public void setStreet(String street) throws IllegalAccessException;
public String getZip();
public void setZip(String zip) throws IllegalAccessException;
}
class MutableAddress implements Address {
String number;
String street;
String zip;
@Override
public String getNumber() {
return number;
}
@Override
public void setNumber(String number) {
this.number = number;
}
@Override
public String getStreet() {
return street;
}
@Override
public void setStreet(String street) {
this.street = street;
}
@Override
public String getZip() {
return zip;
}
@Override
public void setZip(String zip) {
this.zip = zip;
}
}
class ImmutableAddress implements Address {
private final Address address;
public ImmutableAddress(Address address) {
this.address = address;
}
@Override
public String getNumber() {
return address.getNumber();
}
@Override
public void setNumber(String number) throws IllegalAccessException {
throw new IllegalAccessException("Cannot write to this field.");
}
@Override
public String getStreet() {
return address.getStreet();
}
@Override
public void setStreet(String street) throws IllegalAccessException {
throw new IllegalAccessException("Cannot write to this field.");
}
@Override
public String getZip() {
return address.getZip();
}
@Override
public void setZip(String zip) throws IllegalAccessException {
throw new IllegalAccessException("Cannot write to this field.");
}
}
或者,将其包裹在Proxy中。这要复杂得多,但是当您无法访问来源时可以提供帮助。
答案 1 :(得分:1)
所以你需要:
1.使最终和私人的可变课程。
2.对于任何可变对象,您必须防止从外部看到对该对象的引用。
在这种情况下,#2可能意味着您不能像使用getAddress()那样返回对Address的引用。你必须在构造函数中制作一个防御性副本。即,制作任何可变参数的副本,并将副本存储在Employee中。如果你不能制作防御性副本,那么就没有办法让员工不变。
public final class Employee{
private final int id;
private final Address address;
public Employee(int id, Address address)
{
this.id = id;
this.address=new Address(); // defensive copy
this.address.setStreet( address.getStreet() );
}
pulbic int getId(){
return id;
}
public Address getAddress() {
Address nuAdd = new Address(); // must copy here too
nuAdd.setStreet( address.getStreet() );
return nuAdd;
}
How can we maintain Immutability of a class with a mutable reference