如何打破String类的不变性,任何人都可以解释下面的代码



字符串类使"公共类最终字符串"的原因是什么? 下面我写了一个没有最终关键字的不可变类。任何人都可以打破这个类不变性。

mport java.util.Date;
public class Person {
    private final String name;
    private final Date dob;
    public Person(String name, Date dob) {
        this.name = name;
        this.dob = dob;
    }
    public String getName() {
        System.out.println("in person :" + name);
        return this.name;
    }
    public Date getDob() {
        System.out.println("in person :" + dob);
        return this.dob;
    }
}

您尚未编写不可变类,因为缺少该类的final修饰符。
或者,您需要为方法getName()getDob()提供一个final修饰符,以便此字段不可变。

在您的示例中,仍然可以使用子类"修改"类。例如:

public class EditablePerson extends Person {
    // create new fields for name and dob
    // this is possible because the private fields of the superclass are not visible
    private String name;
    private Date  dob;
    public EditablePerson(String name,Date dob){
        // call the constructor of the super-class with dummy-data
        super("garbage", null);
        this.name=name;
        this.dob=dob;
    }
    @Override
    public String getName(){
        System.out.println("in person :"+name);
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public Date getDob(){
        System.out.println("in person :"+dob);
        return this.dob;
    }
    public void setDob(Date dob) {
        this.dob = dob;
    }
}

要对此进行测试,请执行以下操作:

Person p=new EditablePerson("P", new Date());
p.getName();
if(p instanceof EditablePerson) {
    ((EditablePerson)p).setName("Changed");
}
p.getName();

正如@Tom所指出的:

类 Person 也不是不可变的,因为它有一个带有可变类的字段(类Date是可变的(,可以从外部更改。

下面是示例:

Person p=new Person("P",new Date());
p.getDob();
p.getDob().setTime(0l);
p.getDob()

另请阅读:定义不可变对象的策略

声明

final的类不能用作基类。 没有人可以向其添加属性或方法。参见在 Java

public class MutablePerson extends Person {
    private Gender gender;
    public MutablePerson(String name,Date dob, Gender gender) {
        super(name, dob);
        this.gender = gender;
    }
    public final Gender getGender() { return gender; }
    public final void setGender(Gender g) { gender = g; }
    // Override hashcodes and equals as required.
}
public Person getPerson() { return new MutablePerson("Richard", new Date(), Gender.MALE); }
Person person = getPerson(); // Cannot assume person is immutable.

你去吧,这不再是一成不变的。

相关内容

最新更新