Java constructors and encapsulation

Initialize private fields and validate changes through methods.

Java
class Counter {
    private int value;
    Counter(int start) {
        if (start < 0) throw new IllegalArgumentException("negative start");
        value = start;
    }
    void increment() { value++; }
    int getValue() { return value; }
}
class Main {
    public static void main(String[] args) {
        Counter first = new Counter(2);
        Counter second = new Counter(10);
        first.increment();
        System.out.println(first.getValue());
        System.out.println(second.getValue());
    }
}
Output
3
10

Explanation

A constructor initializes a new instance. Private fields keep normal external code from modifying state directly; methods define allowed operations.

This Counter rejects negative starting values and exposes a getter. Two instances have separate fields even though they share the same class definition.

Explore the dry run
Guided walkthroughReady
1class Counter {
2 private int value;
3 Counter(int start) {
4 if (start < 0) throw new IllegalArgumentException("negative start");
5 value = start;
6 }
7 void increment() { value++; }
8 int getValue() { return value; }
9}
10class Main {
11 public static void main(String[] args) {
12 Counter first = new Counter(2);
13 Counter second = new Counter(10);
14 first.increment();
15 System.out.println(first.getValue());
16 System.out.println(second.getValue());
17 }
18}

Follow the example

Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.

View the complete dry-run table
Prepared trace of the published program. Some rows group repeated iterations.
Step / lineWhat happensState after stepOutput so far
Construct the first object.first.value = 2
—
Construct independent state.second.value = 10
—
Change only first.first.value = 3, second.value = 10
—
Read the first value.first.value = 3, second.value = 10
3
Read the unchanged second value.first.value = 3, second.value = 10
3
10

Cost and common mistakes

O(1) operations and O(1) state per instance.

  • A static field would be shared across instances.
  • This minimal counter does not guard integer overflow after many increments.

Try it yourself

Call second.increment() twice.

Reveal answer and reasoning

The output becomes 3 and 12.

Further reading