Good Code
The good version models identity as a value object. Java records give consistent equality and hash behavior, while the constructor keeps invalid values out.
Lesson 03
Use small value objects or records for identity values so equality, hashing, and validation stay together.
public record UserId(UUID value) {
public UserId {
Objects.requireNonNull(value, "value");
}
public static UserId parse(String rawValue) {
return new UserId(UUID.fromString(rawValue));
}
}public class User {
private String id;
private String displayName;
@Override
public boolean equals(Object other) {
if (!(other instanceof User user)) {
return false;
}
return displayName.equals(user.displayName);
}
}The good version models identity as a value object. Java records give consistent equality and hash behavior, while the constructor keeps invalid values out.
The bad version compares users by display name and overrides equals without a matching hashCode. Collections such as HashSet and HashMap can behave incorrectly.