Private method nothing in its class calls

ID

apex.maintainability.unused_private_method

Severity

info

Remediation Complexity

medium

Remediation Risk

medium

Remediation Effort

low

Resource

Dead Code

Language

Apex

Description

Reports a private method that no other method of the same class calls, whether plainly (fee(x)), through this, or through a qualified reference (RefundProcessor.cap()). Any annotated private method is skipped, since an annotation is what makes it reachable from outside. A call made from inside a System.runAs block counts, and a qualified call is recognised when it is qualified by this or by the class’s own name. Three limits are worth knowing: a call made through some other reference to the same class (otherInstance.helper()) is not recognised; a private method called only from an inner class of the same file is still reported, because a class-body match does not descend into a nested class; and a method whose only caller is itself is reported, which is usually correct.

Rationale

A private method is reachable from one class and nowhere else, so if that class never calls it the platform can never run it. It is nonetheless deployed, counted against the org’s Apex character limit, and - because Salesforce measures coverage over deployed lines - it drags the org’s coverage percentage down unless a test was written to call the very method nothing uses. Teams usually respond by writing that test, which makes the dead code permanent and hides the deletion that was actually wanted. It also misleads: a reader looking for how a case is handled finds a method that looks like the handler and is not.

The following code illustrates the pattern detected by this rule:

public class RefundProcessor {

    private static RefundProcessor instance;

    private RefundProcessor() {
        System.debug(LoggingLevel.FINE, 'built');
    }

    public static RefundProcessor getInstance() {
        if (instance == null) {
            instance = new RefundProcessor();
        }
        return instance;
    }

    // FLAGGED: Private method nothing in its class calls
    private Decimal legacyFee(Decimal amount) {
        return amount * 0.05;
    }

    // FLAGGED: Private method nothing in its class calls
    private String legacyLabel(String status) {
        return 'refund-' + status;
    }

    private Decimal fee(Decimal amount) {
        return amount * 0.02;
    }

    private String label(String status) {
        return 'refund-' + status;
    }

    private Boolean isRefundable(Order o) {
        return o.Status == 'Activated';
    }

    private static Decimal cap() {
        return 500;
    }

    @TestVisible
    private Decimal internalRate() {
        return 0.02;
    }

    public Decimal process(Order o, Decimal amount) {
        if (!isRefundable(o)) {
            return 0;
        }
        Decimal charged = fee(amount);
        System.debug(LoggingLevel.INFO, this.label(o.Status));
        System.debug(LoggingLevel.INFO, RefundProcessor.cap());
        return charged;
    }

    public void audit(Order o) {
        System.debug(LoggingLevel.INFO, o.Id);
    }
}

Remediation

Delete the method, together with any private helper that only it called. Where it is genuinely needed from outside the class - by a test, or by a Flow or a Lightning component - widen it deliberately: @TestVisible for a test, @AuraEnabled or @InvocableMethod for a platform caller, rather than leaving it private and unreachable.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved