Confused Inheritance

ID

java.confused_inheritance

Severity

info

Remediation Complexity

medium

Remediation Risk

low

Remediation Effort

medium

Resource

Code Smell

Language

Java

Tags

code-style

Description

Reports protected fields declared in a final class.

Rationale

final on a class forbids subclassing. Inside a non-subclassable class, protected is functionally identical to package-private — there are no subclasses to whom the additional visibility could matter. Mixing the two sends a contradictory signal: "this class is closed for extension and I want subclasses to see this field".

Either drop final (if extension is intended) or change the field’s visibility to package-private / private (if extension is intentionally forbidden). The fix is purely about expressing intent — the runtime semantics are unchanged.

// Bad
public final class Account {
    protected int balance;        // protected is meaningless here
}

// Good — pick the visibility that matches the design
public final class Account {
    private int balance;
}

Remediation

Change protected to the visibility that actually reflects the design (typically private or package-private), or remove the final modifier from the class if subclassing is intended.