Mismatched Finalizer Signature

ID

java.no_overload_finalize

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Java

Tags

best-practice, reliability

Description

Reports a method named finalize whose signature is not void finalize().

Only that exact signature overrides Object.finalize(). A method that adds a parameter, or returns a value, is an unrelated method that happens to share the name — and the garbage collector will never call it.

Rationale

class DraftReport {
  private int revision;

  void finalize(int nextRevision) {   // an overload, not the finalizer
    revision = nextRevision;
  }
}

class SummaryReport {
  private int total;

  private int finalize() {            // right parameters, wrong return type
    return total;
  }
}

Both methods are dead weight in practice. The collector will not invoke them, because neither overrides the finalizer. Callers will not invoke them either, because a method called finalize reads as something the runtime owns. Any cleanup written inside silently never runs, and a reader auditing the class for resource handling is actively misled.

The second form only compiles because a private method does not participate in overriding — which is exactly what makes it easy to miss in review.

Remediation

Give the method a name that says what it does. The confusion disappears and the method becomes callable:

class DraftReport {
  private int revision;

  void applyRevision(int nextRevision) {
    revision = nextRevision;
  }
}

If the intent really was to hook object teardown, do not use finalization: it runs at an unpredictable time, may never run at all, and swallows exceptions. Implement AutoCloseable and let callers use try-with-resources, or register the resource with a java.lang.ref.Cleaner.

© 2026 Xygeni. All rights reserved