Reputation: 637
why we must do Defensive Copying in order to achieve Immutable class? Look at this code:
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
}
}
Why it won't be Immutable if we didn't do Defensive Copying?
Upvotes: 3
Views: 1723
Reputation: 11234
Because otherwise it is possible to change the object state. Let's imagine, that your getDate
method is the following:
public Date getDate() {
return date; // instead of Date
}
And we use it in the following way:
EmailMessage msg = new EmailMessage(...); // initialization
Date date = msg.getDate();
date.setTime(...); //ooops, our msg object has another date now
Upvotes: 2
Reputation: 726619
In order to achieve immutability you must make copies of all mutable objects passed into your constructor, and also return copies for all mutable objects stored inside your class, if any.
In your specific example, Date
class is mutable. If yo skip copying in the constructor, malicious code can do this:
Date d = new ...
EmailMessage msg = new EmailMessage("lazy dog", "quick brown fox", "Jump!", d);
d.setTime(d.getTime()+12345); // Changes the date inside msg
If you skip the second copy, the callers can do this:
EmailMessage msg = ...
Date d = msg.getDate();
d.setTime(d.getTime()+12345); // Changes the date inside msg
Upvotes: 4