It’s good that you made the student semantically unchanged:
- His attributes are final
- they have immutable types (except address)
- and they are initialized in the constructor.
You must apply the same thing to the Address class so that it becomes unchanged, and then the entire Student state will be unchanged. So it will be:
public final class Address { private final int aid; private final String street; public Address(int aid, String street) { this.aid = aid; this.street = street; } public int getAid() { return aid; } public String getStreet() { return street; } .... }
Fortunately, you do not have any modifiable types (some of the most famous are Date , Collection and Maps ), otherwise you will also consider them.
If you have any mutable attributes, you must copy it to the constructor, and you must return an immutable copy or a copy of it where the state leak occurs.
For example, if your Student class had the birthDate attribute, you should do something like:
public final class Student { private final Date birthDate; public Student(int sid, String name, Address address, Date birthDate) { this.sid = sid; this.name = name; this.address = address; this.birthDate = (birthDate == null) ? null : new Date(birthDate.getTime()); } public Date getBirthDate() { return (birthDate == null) ? null : new Date(birthDate.getTime()); } .... }
Amir pashazadeh
source share