1. The Constructor: Customs Gate of Invariants
An invariant is a domain rule that must NEVER be broken (e.g. grade 0-10, non-negative balance). The constructor is the customs officer: invalid arguments are replaced with a safe default and logged to the console. The object is always allocated, but never with broken data.
Grade satisfies the invariant (0 to 10). The object is safely instantiated in the Heap.
2. Constructor Overloading and this() Delegation
Multiple constructors shouldn’t duplicate validation logic. With this(...), auxiliary constructors delegate to a single canonical constructor. Crucial rule: this() must be the very first statement.
Rules live in ONE single method. If price invariants change, you only maintain one place.
3. The 4 Access Modifiers Matrix
Java offers 4 concentric visibility scopes. The golden rule is Least Privilege: default to private, opening up only when strictly required by architecture.
Ideal for state fields. No external entity can read or write values directly.
4. The Reference Leak Threat
Marking a field private does NOT guarantee encapsulation if a getter exposes a direct reference to a mutable object (like an array or Date). Callers can corrupt your internal array behind your back.
Exposing the internal reference completely broke encapsulation. The client corrupted the medical records.
5. Immutability: Flawless Encapsulation
An immutable class (like String, LocalDate, or Java 16+ records) defines private final fields with no setters. It is thread-safe by design since its internal state never mutates once created.
Immutability eliminates entire classes of bugs at once: data races, accidental aliasing, and state corruption.