If you want to implement a class that stores the first and last name of a person, you would normally implement something like this:
public class PersonMutable {
private String firstName;
private String lastName;
private Date birthDate;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
}
You can convert this class into an immutable class by following the rules explained earlier. The following is the result:
public final class PersonImmutable {
final private String firstName;
final private String lastName;
final private Date birthDate;
public PersonImmutable (String firstName, String lastName,
String address, Date birthDate) {
this.firstName=firstName;
this.lastName=lastName;
this.birthDate=birthDate;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public Date getBirthDate() {
return new Date(birthDate.getTime());
}
}
Essentially, you followed the basic principles of an immutable class, which are as follows:
- The class is marked as final.
- The attributes are marked as final and private.
- The value of the attributes can only be established in the constructor of the class.
Its methods return the value of an attribute, but they don't modify them. - For mutable attributes (the birthDate attribute in our case), we return a defensive copy of the get() method by creating a new object.