---
schema_version: "1"
id: d074ddfa9443732b0db208d9037f71e1d446e10b6c9426548c5f4a25ac24c53b
title: Safe Navigation Operator
collection: legacydeveloper
version: current
locale: en-us
portal_url: https://docs.salesforce.com/legacydeveloper/current/en-us/apexcode/langCon_apex_SafeNavigationOperator.md
canonical_url: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SafeNavigationOperator.htm
source_site: developer.salesforce.com
content_type: documentation
content_hash: 3ce7575d1c065feb7a8f0d4cee5f1df11207cd6eedd282e0138fe9956852e08e
description: Use the safe navigation operator (?.) to replace explicit, sequential checks for null references. This operator short-circuits expressions that attempt to operate on a null value and returns null instead of throwing a NullPointerException.
---
# Safe Navigation Operator

Use the safe navigation operator (?.) to replace explicit, sequential checks for null references. This operator short-circuits expressions that attempt to operate on a null value and returns null instead of throwing a NullPointerException.

![Important](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/images/icon_note_important.png)

#### Important

Where possible, we changed noninclusive terms to align with our company value of Equality. We maintained certain terms to avoid any effect on customer implementations.

If the left-hand-side of the chain expression evaluates to null, the right-hand-side isn’t evaluated. Use the safe navigation operator (?.) in method, variable, and property chaining. The part of the expression that isn’t evaluated can include variable references, method references, or array expressions.

![Note](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/images/icon_note.png)

#### Note

All Apex types are implicitly nullable and can hold a null value returned from the operator.

## Examples

- This example first evaluates a, and returns null if a is null. Otherwise the return value is a.b.
    
    a?.b // Evaluates to: a == null ? null : a.b
- This example returns null if a\[x\] evaluates to null. If a\[x\] doesn’t evaluate to null and aMethod() returns null, then this expression throws a NullPointerException.
    
    a\[x\]?.aMethod().aField // Evaluates to null if a\[x\] == null
- This example returns null if a\[x\].aMethod() evaluates to null.
    
    a\[x\].aMethod()?.aField
- This example indicates that the type of the expression is the same whether the safe navigation operator is used in the expression or not.
    
    Integer x = anObject?.anIntegerField; // The expression is of type Integer because the field is of type Integer
- This example shows a single statement replacing a block of code that checks for nulls.
    
    // Previous code checking for nulls
    String profileUrl = null;
    if (user.getProfileUrl() != null) {
        profileUrl = user.getProfileUrl().toExternalForm();
    }
    
    // New code using the safe navigation operator
    String profileUrl = user.getProfileUrl()?.toExternalForm();
- This example shows a single-row SOQL query using the safe navigation operator.
    
    // Previous code checking for nulls
    results = \[SELECT Name FROM Account WHERE Id = :accId WITH USER\_MODE\];
    if (results.size() == 0) { // Account was deleted
        return null;
    }
    return results\[0\].Name;
    
    // New code using the safe navigation operator
    return \[SELECT Name FROM Account WHERE Id = :accId WITH USER\_MODE\]?.Name;

Table 1. Safe Navigation Operator Use-Cases
| Allowed use-case | Example | More information |
| --- | --- | --- |
| Method or variable or parameter chains | aObject?.aMethod(); | Can be used as a top-level statement. |
| Using parentheses, for example in a cast. | ((T)a1?.b1)?.c1() | The operator skips the method chain up to the first closing parenthesis. By adding the operator after the parenthesis, the code safeguards the whole expression. If the operator is used elsewhere, and not after the parenthesis, the whole cast expression isn’t be safeguarded. For an example, see [Incorrect use of safe navigation operator with cast](#ex_cast). |
| SObject chaining | String s = contact.Account?.BillingCity; | An SObject expression evaluates to null when the relationship is null. The behavior is equivalent to String s = contact.Account.BillingCity. |
| SOQL Queries | String s = \[SELECT LastName FROM Contact\]?.LastName; | If the SOQL query returns no objects, then the expression evaluates to null. For an example, see [SOQL query with safe navigation operator: behavior when no records returned](#ex_soql). |

## Incorrect use of safe navigation operator with cast

//Incorrect use of safe navigation operator
((T)a1?.b1).c1()

This is equivalent to:

T ref = null;
if (a1 != null) {
    ref = (T)a1.b1;
}
result = ref.c1();

## SOQL query with safe navigation operator: behavior when no records returned

List<Contact> contacts = \[SELECT LastName FROM Contact WITH USER\_MODE\]; 
String s; 
if (contacts.size() == 0) { 
    s = null; // New behavior when using Safe Navigation. Earlier, this would throw an exception. 
} else if (contacts.size() == 1) { 
    s = contacts.get(0).LastName; 
} else { 
    // contacts.size() > 1 throw new QueryException(...); 
}

You can’t use the Safe Navigation Operator in certain cases. Attempting to use the operator in these ways causes an error during compilation:

- Types and static expressions with dots. For example:
    - Namespaces
    - {Namespace}.{Class}
    - Trigger.new
    - Flow.interview.{flowName}
    - {Type}.class
- Static variable access, method calls, and expressions. For example:
    - AClass.AStaticMethodCall()
    - AClass.AStaticVariable
    - String.format('{0}', 'hello world')
    - Page.{pageName}
- Assignable expressions. For example:
    - foo?.bar = 42;
    - ++foo?.bar;
- SOQL bind expressions. For example:
    
    public with sharing class X {
        public String query = 'xyz';
    } 
    X x = new X(); 
    List<Account> accounts = \[SELECT Name FROM Account WHERE Name = :X?.query WITH USER\_MODE\]
    List<List<SObject>> moreAccounts = \[FIND :X?.query IN ALL FIELDS 
        RETURNING Account(Name)\];
- With addError() on SObject scalar fields. For example:
    
    Contact c; 
    c.LastName?.addError('The field must have a value');
    
    ![Note](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/images/icon_note.png)
    
    #### Note
    
    You can use the operator with addError() on SObjects, including lookup and master-detail fields.