java - 为什么我们必须对不可变类进行防御性复制

标签 java immutability copying

为什么我们必须进行防御性复制才能实现不可变类? 看这段代码:

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
    }
}

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

最佳答案

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

  • 如果您不复制传递给您的日期,调用者可以在您的对象构建后更改日期,从而有效地改变它。
  • 如果您不从可变对象的 getter 返回副本,则调用者可以改变他们从您那里获得的对象,从而有效地改变您的对象。

在您的具体示例中,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

关于java - 为什么我们必须对不可变类进行防御性复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29386299/

相关文章:

c - 如何从 argv[] 中获取 memcpy()?

电影院定时显示程序

java - 如何将文本文件中的值存储到适当的变量中,以及如何使该代码块更清晰?

java - 多张图片上传 OOM 问题

r - 使 R 函数返回锁定/不可变列表

javascript - 计算(ImmutableJS) map 的所有项目?

java - Spring Oauth2 Authorization_Grant - token 后无法访问资源 - 匿名用户

java - StringBuffer 如何通过类中没有字段的空隙传递数据?

javascript - 使用 String.prototype 扩展 String 时无法覆盖 javascript 中的 "this"

c++ - 防止 C++ 中的意外对象复制