100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

What is an Invariant in OOP?

Learn what a class invariant is in OOP — state consistency enforced by encapsulation before and after methods — with a Java example and Q&A.

mediumQ155 of 226 in Object Oriented Programming Est. time: 5 minsLast updated:
Open Code Lab

Expected Interview Answer

A class invariant is a condition about an object’s state that must hold true at every point the object is observable from outside — after construction completes and after every public method returns — even though it may be temporarily broken during a method’s internal execution.

Invariants are typically established in the constructor and then preserved by every public method: each method may temporarily violate the invariant partway through its work, but must restore it before returning control to the caller. Encapsulation is what makes invariants enforceable at all — if fields were public, any external code could set the object into an invalid state directly, bypassing the methods responsible for maintaining consistency. A classic example is a balanced binary search tree, whose balance-factor invariant may be violated momentarily during an insertion but is always restored by rebalancing before the insert operation returns. Invariants are closely related to Design by Contract, where the invariant is the third contract element alongside preconditions and postconditions, checked implicitly at the start and end of every public operation.

  • Guarantees an object is always in a valid, usable state between operations
  • Lets other code reason about an object without inspecting its full internals
  • Localizes correctness responsibility to the class's own methods
  • Provides a systematic way to think about what can safely break temporarily during a method

AI Mentor Explanation

Between deliveries, a team must always have exactly eleven fielders on the ground — that’s the invariant. During a substitution, there might be a fleeting moment with ten or twelve players as one runs off and another runs on, but by the time the umpire signals ready for the next ball, the count of eleven must be restored. An OOP invariant works the same way: it can be momentarily broken inside a method’s execution, but it must always hold again by the time that method returns control to the caller.

Step-by-Step Explanation

  1. Step 1

    Establish the invariant in the constructor

    Ensure the object starts life in a state that already satisfies the invariant.

  2. Step 2

    Identify which methods could break it

    Determine which mutating operations touch the fields the invariant depends on.

  3. Step 3

    Allow temporary violation internally

    A method may leave the object briefly inconsistent while it performs multi-step work.

  4. Step 4

    Restore before returning

    Every public method must re-establish the invariant before control returns to the caller.

What Interviewer Expects

  • Correct definition: a condition true before and after every public method, not necessarily during it
  • Understanding that encapsulation is what makes invariants enforceable
  • A concrete example (balanced tree, non-negative balance, etc.)
  • Connection to Design by Contract as the invariant clause

Common Mistakes

  • Claiming an invariant must hold at every line of code, including mid-method
  • Believing invariants are optional documentation rather than enforceable via encapsulation
  • Confusing an invariant with a precondition or postcondition of a single method
  • Forgetting that public fields make invariants impossible to guarantee from within the class alone

Best Answer (HR Friendly)

An invariant is a rule about an object that must always be true whenever outside code can see or use that object — for example, a bank balance can never be negative. It’s fine for that rule to be technically broken for a moment while a method is doing its internal work, but the method must fix it before it finishes, so the object is always valid whenever anyone else looks at it.

Code Example

Class invariant maintained across a method
class BankAccount {
    private double balance;

    BankAccount(double initial) {
        if (initial < 0) throw new IllegalArgumentException();
        this.balance = initial; // invariant established: balance >= 0
    }

    // Invariant: balance must never be negative after this returns
    void transfer(BankAccount to, double amount) {
        if (amount <= 0 || amount > this.balance) {
            throw new IllegalArgumentException();
        }
        this.balance -= amount; // momentarily: money "in flight"
        to.balance += amount;   // invariant restored on both accounts
        // Both accounts satisfy balance >= 0 again before this returns
    }
}

Follow-up Questions

  • How does encapsulation make invariants enforceable?
  • What is the relationship between an invariant and a precondition/postcondition?
  • Can an invariant be temporarily violated, and if so, when?
  • How would you unit test that a class invariant holds?

MCQ Practice

1. A class invariant must hold true?

Invariants apply at externally observable points: after construction and after every public method call, not mid-method.

2. What language feature makes invariants enforceable in practice?

Encapsulation prevents external code from directly setting fields into a state that violates the invariant.

3. Within Design by Contract, an invariant is?

Invariants form the third pillar of Design by Contract alongside preconditions and postconditions.

Flash Cards

Invariant in one line?A condition about an object's state that holds true before and after every public method call.

Can it break mid-method?Yes, temporarily — it just must be restored before the method returns.

What enforces it?Encapsulation — private fields prevent external code from bypassing the invariant.

Relation to Design by Contract?It is the third contract element, alongside preconditions and postconditions.

1 / 4

Continue Learning