I believe this is the case that justifies this statements:
public class Immutable {
private final String name;
private Date dateOfBirth;
public Immutable(String name, Date dateOfBirth) {
this.name = name;
this.dateOfBirth = dateOfBirth;
}
public String getName() {
return name;
}
public Date getDateOfBirth() {
return dateOfBirth;
}
}
getName()
is fine as it returns immutable object as well. However the getDateOfBirth()
method can break immutability because the client code can modify returned object, hence modifying the Immutable
object as well:
Immutable imm = new Immutable("John", new Date());
imm.getName(); //safe
Date dateOfBirth = imm.getDateOfBirth();
//hundreds of lines later
dateOfBirth.setTime(0); //we just modified `imm` object
It is safe to return immutable objects and primitives (as they are returned by value). However you need to make defensive copies of mutable objects, like Date
:
public Date getDateOfBirth() {
return new Date(dateOfBirth.getTime());
}
and wrap collections in immutable views (if they are mutable), e.g. see Collections.unmodifiableList()
:
public List<Integer> getSomeIds() {
return Collections.unmodifiableList(someIds);
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…