String literal of twelve or more characters written four or more times
ID |
apex.maintainability.duplicated_string_literal |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Readability |
Language |
Apex |
Description
Reports a string literal of twelve or more characters written four or more times inside the same class (fixed thresholds: 12 characters, 4 occurrences), once per literal. Shorter literals, literals shaped like an API name (Name, CurrencyIsoCode, Donation_Date__c) and repetitions spread across separate files are not reported.
Rationale
A literal this long repeated this often is a value with a meaning - a picklist entry, an endpoint path, an error message a user reads, the string a test asserts on - and every copy is a place that has to change together with the others. The compiler catches a mistyped constant name; it cannot catch a mistyped copy of a string, so a copy that was missed does not fail to compile, it silently stops matching and the records it was supposed to pick up are skipped. Change a picklist value in Setup, or the wording of a message in one place only, and the divergence surfaces as wrong data or as two different messages for the same condition rather than as a deployment error.
The following code illustrates the pattern detected by this rule:
public class ShipmentNotifier {
public void notifyAll(List<Case> cases) {
for (Case c : cases) {
// FLAGGED: String literal of twelve or more characters written four or more times
c.Description = 'Shipment delayed at customs';
}
System.debug('Shipment delayed at customs');
System.debug('Shipment delayed at customs');
System.debug('Shipment delayed at customs');
}
}
Remediation
Declare the value once as a private static final String constant on the class - or, for anything a user reads, as a Custom Label, so it can be translated and changed without a deployment - and reference that everywhere. Where the literal is a picklist value, prefer the describe API (getPicklistValues) over any literal at all, so the value is resolved from the metadata rather than copied into the code.