Constructor Calls Overridable Method

ID

java.constructor_calls_overridable

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Java

Tags

CWE:580, reliability

Description

Reports constructors that call overridable (non-final, non-private, non-static) methods on this.

Rationale

When a constructor calls an overridable method, a subclass can override that method. Because the subclass constructor has not yet executed when the superclass constructor runs, the overridden method may access fields that are still in their default-initialized state (null, 0, false). This leads to subtle, hard-to-reproduce bugs.

// Bad -- subclass override runs before SubClass() body
class Base {
    Base() {
        setup(); // overridable
    }
    void setup() { /* default */ }
}

class SubClass extends Base {
    private String name;
    SubClass() {
        name = "initialized";
    }
    @Override
    void setup() {
        // name is still null here!
        System.out.println(name.length());
    }
}

Remediation

Make the called method private, final, or static so that it cannot be overridden. Alternatively, move the initialization logic out of the constructor and into a factory method.

class Base {
    Base() {
        doSetup(); // safe — cannot be overridden
    }
    private void doSetup() { /* ... */ }
}