编程语言
首页 > 编程语言> > Java防御性复制和不可变

Java防御性复制和不可变

作者:互联网

为什么必须进行防御性复制才能实现不可变类?
看下面的代码:

public final class EmailMessage   {
    private final String from;
    private final String to;
    private final String message;
    private final Date   date;

    public EmailMessage( String from, String to, String msg, Date date )
    {
        this.to = to;
        this.from = from;
        this.message = msg;
        this.date = new Date(date.getTime());// instead of date;
    }

    public String getFrom()
    {
        return( from );
    }

    public Date getDate() {
        return( new Date( date.getTime() ); // instead of Date
    }
}

如果我们不进行防御性复制,为什么它不会一成不变?

解决方法:

为了实现不变性,您必须复制传递给构造函数的所有可变对象的副本,还必须为存储在类中的所有可变对象返回副本.

>如果您不复制传递给您的日期,则调用者可以在构造对象之后更改日期,从而有效地更改日期.
>如果您不从可变对象的获取器返回副本,则调用者可以更改从您那里获得的对象,也可以有效地更改您的对象.

在您的特定示例中,Date类是可变的.如果您跳过在构造函数中的复制,则恶意代码可以执行以下操作:

Date d = new ...
EmailMessage msg = new EmailMessage("lazy dog", "quick brown fox", "Jump!", d);
d.setTime(d.getTime()+12345); // Changes the date inside msg

如果您跳过第二个副本,则调用者可以执行以下操作:

EmailMessage msg = ...
Date d = msg.getDate();
d.setTime(d.getTime()+12345); // Changes the date inside msg

标签:copying,immutability,java
来源: https://codeday.me/bug/20191028/1952968.html