String Class Apex: Methods & Examples | SalesforceTutorial

Written by Prasanth Kumar Published on Updated on

Scope: This string class apex article focuses on Apex code, not formula functions, Data Cloud SQL, or AMPscript string functions.

string class apex refers to the built-in System.String type and its methods for checking, comparing, splitting, replacing, and extracting text in Apex. Use it when you validate text fields, parse API payload values, build safe search terms, normalize emails, read picklist values, or prepare messages for Flow, LWC, and integrations.

This guide uses the current Salesforce Apex Reference Guide for the String class as the source of truth. The examples avoid Beta and Pilot features, and the test code follows the deployment rule that Apex tests must pass and meet Salesforce coverage requirements before production deployment.

String Class Apex: what does it do?

The String class apex developers use is not a custom class that you create. It is the platform type Salesforce provides for text values. In Apex, values from fields such as Account.Name, Contact.Email, custom Text fields, Text Area fields, URL fields, and most picklist values are handled as String values in code.

The main job of the salesforce string class is to let you ask questions about text or return a changed copy of text. For example, you can check whether an email contains @, extract the first part of an order reference, trim spaces from a Flow input, or compare a value without caring about letter case. The original variable does not change unless you assign the returned value back to a variable.

For related Apex fundamentals, see Apex code examples for Salesforce developers and Salesforce API integration patterns.

Salesforce string class behavior with fields and picklists

The salesforce string class is common because many business rules start with text. A lead source might need trimming before assignment. An email domain might drive routing. A picklist API value might decide whether a record qualifies for automation. Treat these values as business data, not just characters.

For picklists, read the allowed values from metadata when your code must validate or display choices. Do not hardcode values into a service class unless the value is stable and controlled by your release process. Restricted picklists can reject values that are not in the configured list during DML, so check metadata or centralize the mapping.

public with sharing class PicklistTextService {
    public static Set<String> getActiveOpportunityStageValues() {
        Set<String> stageValues = new Set<String>();

        Schema.DescribeFieldResult fieldDescribe =
            Opportunity.StageName.getDescribe();

        for (Schema.PicklistEntry entry : fieldDescribe.getPicklistValues()) {
            if (entry.isActive()) {
                stageValues.add(entry.getValue());
            }
        }

        return stageValues;
    }
}

Use getValue() when your Apex logic needs the stored picklist API value. Use getLabel() only when the label is the intended output for a user-facing message.

How do string methods sfdc developers use most often?

The phrase string methods sfdc usually points to the methods developers reach for in triggers, controllers, batch jobs, and integration handlers. The table below groups the methods by job instead of listing every method alphabetically.

Task Methods What to check before using
Null and blank checks String.isBlank(), String.isNotBlank() Use the static methods before calling instance methods on a value that might be null.
Comparison equals(), equalsIgnoreCase(), startsWith(), endsWith() Decide whether case should matter. Salesforce IDs, picklist API values, and email domains have different rules.
Search inside text contains(), indexOf(), lastIndexOf() contains() is case-sensitive, so normalize case when business matching is case-insensitive.
Extract text substring(), split(), charAt() Guard index positions. Apex indexes start at 0, and substring end positions are exclusive.
Clean or format trim(), replace(), replaceAll(), toLowerCase(), toUpperCase() Remember that regular expressions apply to methods such as replaceAll() and split().
Convert to text String.valueOf() Use it when you need a readable text representation of an Id, number, Boolean, Date, or other supported value.

In enterprise orgs, the safest pattern is to wrap repeated string methods sfdc logic in a utility or domain service class. That keeps validation consistent across triggers, Queueable jobs, screen Flow actions, and LWC Apex controllers.

String methods sfdc examples for null handling

Null handling is the first rule of string class apex work. Calling trim(), contains(), or substring() on a null variable throws a runtime exception. Use String.isBlank() when null, empty text, and spaces should all be treated as missing.

public with sharing class AccountTextNormalizer {
    public static String normalizeAccountKey(String name, String billingCountry) {
        List<String> pieces = new List<String>();

        if (String.isNotBlank(name)) {
            pieces.add(name.trim().toLowerCase());
        }

        if (String.isNotBlank(billingCountry)) {
            pieces.add(billingCountry.trim().toLowerCase());
        }

        return String.join(pieces, '|');
    }

    public static Boolean emailDomainMatches(String email, Set<String> allowedDomains) {
        if (String.isBlank(email) || allowedDomains == null || allowedDomains.isEmpty()) {
            return false;
        }

        Integer atIndex = email.lastIndexOf('@');
        if (atIndex < 0 || atIndex == email.length() - 1) {
            return false;
        }

        String domain = email.substring(atIndex + 1).toLowerCase();
        return allowedDomains.contains(domain);
    }

    public static String leftSafe(String input, Integer maxLength) {
        if (String.isBlank(input) || maxLength == null || maxLength <= 0) {
            return '';
        }

        return input.length() <= maxLength
            ? input
            : input.substring(0, maxLength);
    }
}

This class does three practical things: it creates a normalized matching key, checks an email domain, and wraps apex substring logic so a caller does not pass an invalid index. The code uses no SOQL and no DML, so it does not consume query or DML governor limits.

How do apex string contains and apex substring work?

The two methods that cause many production bugs are apex string contains and apex substring. Both are simple when the input is clean. Both fail or return the wrong answer when you ignore nulls, case, or index boundaries.

Apex string contains: case-sensitive matching

apex string contains returns true when the calling string includes the requested sequence of characters. The comparison is case-sensitive. If a business rule says “match Renewal, renewal, and RENEWAL,” normalize both sides before calling contains().

String subject = 'Renewal notice for Acme';
Boolean hasRenewal = subject != null
    && subject.toLowerCase().contains('renewal');

System.assertEquals(true, hasRenewal);

Use contains() for small checks, such as detecting a token in a subject line or identifying a domain fragment after you validate the string. Do not use apex string contains as the only validation for structured data such as email, phone, or external IDs. For structured values, parse the parts you need and validate those parts.

Apex substring: indexes, nulls, and length checks

apex substring returns part of a string. The start index is zero-based. The end index, when supplied, is not included in the result. This means 'Salesforce'.substring(0, 5) returns 'Sales', not six characters.

String productCode = 'INV-2026-0042';

String prefix = productCode.substring(0, 3);
String yearText = productCode.substring(4, 8);
String sequence = productCode.substring(9);

System.assertEquals('INV', prefix);
System.assertEquals('2026', yearText);
System.assertEquals('0042', sequence);

Use index checks when the source value comes from a user, an external system, or a CSV file. A fixed-format integration can still send a short or blank value during an upstream defect. A safe apex substring helper prevents one bad row from failing an entire batch.

When to use indexOf before substring

Use indexOf() or lastIndexOf() when delimiters can move. In the email example above, the code finds the final @ instead of assuming a fixed position. That pattern is better for values whose length varies by customer, country, or external source.

Best practices for string class apex in production code

string class apex code often looks harmless because it works on text, but text logic frequently sits near security, integration, and data quality boundaries. The following patterns reduce defects in production orgs.

Normalize once and compare the normalized value

Do not scatter trim().toLowerCase() calls throughout a trigger. Normalize the value once and give the variable a name that explains its purpose.

String rawLeadSource = leadRecord.LeadSource;
String normalizedLeadSource = String.isBlank(rawLeadSource)
    ? ''
    : rawLeadSource.trim().toLowerCase();

if (normalizedLeadSource == 'web') {
    // Route to the web lead queue or apply a web-specific rule.
}

This pattern also makes tests easier to read. If your org uses Flow for lead routing, keep the same normalization rule in an invocable Apex action or a shared formula instead of duplicating it in many places. For automation context, see Salesforce Flow examples and design notes.

Use bind variables instead of dynamic SOQL string concatenation

String operations do not make dynamic SOQL safe by themselves. When you build search features from user input, prefer bind variables. Salesforce documents dynamic SOQL separately from the salesforce string class because query construction has its own security rules.

public with sharing class AccountSearchController {
    public static List<Account> findAccountsByName(String userText) {
        if (String.isBlank(userText)) {
            return new List<Account>();
        }

        String likeTerm = '%' + userText.trim() + '%';

        return [
            SELECT Id, Name
            FROM Account
            WHERE Name LIKE :likeTerm
            ORDER BY Name
            LIMIT 50
        ];
    }
}

The query above uses a bind variable rather than concatenating input into the SOQL statement. If you must create dynamic SOQL, follow Salesforce guidance on dynamic SOQL and SOQL injection prevention. Use String.escapeSingleQuotes() only in the cases where Salesforce recommends it, and do not treat it as a replacement for bind variables.

Use Id.to15() instead of manual ID substring logic

Salesforce record IDs can appear as 15-character or 18-character values depending on context. When code specifically needs the 15-character case-sensitive representation of an 18-character Id, use the documented System.Id to15() method. Do not use apex substring just because the first 15 characters appear to work.

Account acct = new Account(Name = 'Acme');
insert acct;

Id recordId = acct.Id;
String caseSensitiveId = recordId.to15();

System.assertEquals(15, caseSensitiveId.length());

Use this only when a downstream process requires the 15-character value. In most integrations, the 18-character ID is safer because it is case-insensitive.

Split and replace with care when regex is involved

Some string methods sfdc developers use, such as split() and replaceAll(), treat the pattern as a regular expression. That is useful for cleaning phone numbers, but it can surprise teams that expect a plain text replacement.

String rawPhone = '+1 (415) 555-0100';
String digitsOnly = rawPhone.replaceAll('[^0-9]', '');

System.assertEquals('14155550100', digitsOnly);

If the pattern comes from an administrator setting or a custom metadata record, document whether it is plain text or regex. Otherwise, the next release can change matching behavior without an Apex compile error.

What security and governor limits apply to String methods?

Most string class apex methods do not consume SOQL or DML limits directly. They still run inside Apex CPU time and heap limits. Large payload parsing, repeated regex operations, and loops over thousands of records can raise CPU or heap risk, especially in Batch Apex or Queueable jobs that process integration data.

Salesforce documents Apex governor limits in the Apex Developer Guide. In production code, avoid repeated work inside loops. Normalize each value once, store the result in a local variable, and use collections such as Set<String> for membership checks instead of repeatedly scanning long strings.

String sanitization is not CRUD, FLS, or sharing enforcement

Cleaning a string does not grant permission to read or update a field. Apex code that returns record data to LWC, Aura, Visualforce, Flow, or an API response must still follow the org security model. Use sharing declarations for record access and enforce object-level and field-level permissions with patterns documented by Salesforce, such as enforcing object and field permissions.

For example, a controller that searches accounts by name must handle both concerns: the salesforce string class prepares the search text, while the query and returned fields must respect access requirements for the running user.

Test string utility code with positive, negative, and boundary cases

Salesforce requires Apex tests before deployment, and Trailhead explains that at least 75% Apex code coverage is required for deployment or packaging while all tests must pass. For string class apex utilities, do not stop at happy-path tests. Add null, blank, short, long, mixed-case, and delimiter-missing cases.

@IsTest
private class AccountTextNormalizerTest {
    @IsTest
    static void normalizesKeyAndChecksEmailDomain() {
        System.assertEquals(
            'acme|india',
            AccountTextNormalizer.normalizeAccountKey(' Acme ', ' INDIA ')
        );

        Set<String> domains = new Set<String>{ 'example.com' };

        System.assertEquals(
            true,
            AccountTextNormalizer.emailDomainMatches('owner@example.com', domains)
        );

        System.assertEquals(
            false,
            AccountTextNormalizer.emailDomainMatches('owner@blocked.com', domains)
        );
    }

    @IsTest
    static void handlesBlankAndShortValues() {
        System.assertEquals('', AccountTextNormalizer.leftSafe(null, 5));
        System.assertEquals('', AccountTextNormalizer.leftSafe('abc', 0));
        System.assertEquals('abc', AccountTextNormalizer.leftSafe('abcdef', 3));

        System.assertEquals(
            false,
            AccountTextNormalizer.emailDomainMatches('not-an-email', new Set<String>{ 'example.com' })
        );
    }
}

For more test guidance, see Salesforce Trailhead on Apex testing. The test class above avoids SeeAllData, uses no org-specific metadata, and checks boundary behavior. That makes it safer for packaging, scratch orgs, and CI jobs.

Common errors with string class apex

Error or symptom Likely cause Fix
System.NullPointerException Calling an instance method on a null string. Check String.isBlank(value) before trim(), contains(), or substring().
StringException: Starting position out of bounds The apex substring start index is negative or greater than the string length. Check length() and delimiter indexes before extraction.
Search misses values with different case apex string contains and many comparisons are case-sensitive. Normalize both sides with toLowerCase() or use a case-insensitive method where Salesforce provides one.
Dynamic SOQL fails or becomes unsafe User text was concatenated into a query string. Use bind variables first. Use documented dynamic SOQL protections only when dynamic construction is required.
Regex replacement removes more text than expected replaceAll() or split() used a regex pattern. Escape the pattern or use a plain replacement method when the requirement is literal text replacement.

How should admins and developers decide where String logic belongs?

Put simple display formatting in Flow or formulas when admins own the rule and the value is not reused by Apex. Put reusable validation, parsing, or integration cleanup in Apex when the same rule appears in more than one automation path, when tests are required, or when errors need structured handling.

For LWC and API use cases, keep string class apex logic in a service layer rather than inside the controller method. The controller should receive input, call the service, and return a clear response. This makes the same method usable from a REST integration, a Queueable retry job, or a Flow action. For authentication and external app context, see Connected App setup for Salesforce integrations.

How to review string class apex code before deployment

Use this string class apex checklist as a string class apex review aid during pull request review or change-set validation. It catches the defects that usually appear after data volume, language settings, or integration inputs change.

  • string class apex null checks: use String.isBlank() or String.isNotBlank() before instance methods when the value can come from a field, Flow input, request body, or custom metadata.
  • string class apex comparison rules: decide whether case matters before choosing equals(), equalsIgnoreCase(), or normalized lower-case comparison.
  • string class apex extraction rules: check length(), indexOf(), and delimiter positions before calling substring().
  • string class apex SOQL rules: use bind variables for user input, and avoid building a query by concatenating raw text.
  • string class apex picklist rules: compare stored API values, not translated labels, unless the label is the required output.
  • string class apex regex rules: document any replaceAll() or split() pattern that an admin can change outside code.
  • string class apex bulk rules: normalize values once per record and store results in sets or maps when later logic repeats the same lookup.
  • string class apex test rules: include blank, null, mixed-case, short-string, long-string, and delimiter-missing test cases.

Frequently Asked Questions

What is the String class in Apex?

The String class in Apex is Salesforce’s built-in text type and method set for working with text values. In practical string class apex work, the method set includes methods such as contains(), substring(), trim(), split(), replace(), String.isBlank(), and String.valueOf().

Is apex string contains case sensitive?

Yes. In string class apex comparisons, apex string contains is case-sensitive. Convert both strings to the same case before calling contains() when the business rule should ignore case.

How do I use apex substring without errors?

For string class apex extraction, check that the string is not blank and that the start and end indexes are inside the string length. apex substring uses a zero-based start index and an exclusive end index, so substring(0, 3) returns the first three characters.

Which string methods sfdc developers should learn first?

For string class apex basics, start with String.isBlank(), String.isNotBlank(), trim(), contains(), substring(), split(), replace(), replaceAll(), equalsIgnoreCase(), and String.valueOf(). These string methods sfdc developers use cover most validation, parsing, and normalization tasks.

Is the salesforce string class enough to prevent SOQL injection?

No. string class apex methods in the salesforce string class help you clean and inspect text, but SOQL safety depends on query construction. Prefer bind variables. If dynamic SOQL is required, follow Salesforce’s SOQL injection guidance and use escaping only where the documentation recommends it.

Summary

string class apex is part of daily Apex work because most Salesforce automation touches text somewhere. Use String.isBlank() before instance methods, normalize values before comparison, guard apex substring indexes, remember that apex string contains is case-sensitive, and keep repeated text rules in tested utility classes. For production code, combine String methods with governor-limit awareness, secure SOQL patterns, and Salesforce security enforcement.