// Previous code checking for nulls
results = [SELECT Name FROM Account WHERE Id = :accId];
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]?.Name;
:
// 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();
Use the Safe Navigation Operator to Avoid Null Pointer Exceptions
Use the safe navigation operator (?.) to replace explicit, sequential checks for null references. This new operator short-circuits expressions that attempt to operate on a null value and returns null instead of throwing a NullPointerException.
Where: This change applies to Lightning Experience and Salesforce Classic in Enterprise, Performance, Unlimited, and Developer editions.
How: If the left-hand-side of the chain expression evaluates to null, the right-hand-side is not evaluated. Use the safe navigation operator (?.) in method, variable, and property chaining. The part of the expression that is not evaluated can include variable references, method references, or array expressions.
- 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] does not evaluate to null and aMethod() returns null, then this expression throws a null pointer exception.
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]; 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]?.Name;
Method/variable/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 example, the behavior of
//Incorrect use of safe navigation operator
((T)a1?.b1).c1()
is equivalent to:
T ref = null;
if (a1 != null) {
ref = (T)a1.b1;
}
result = ref.c1();
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. The behavior is equivalent to:
List<Contact> contacts = [SELECT LastName FROM Contact];
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(...); }
ou 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:
class X { public String query = 'xyz';} X x = new X(); List<Account> accounts = [SELECT Name FROM Account WHERE Name = :X?.query] 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');
'개발자정보' 카테고리의 다른 글
Salesforce(세일즈포스) Action Function (0) | 2022.04.16 |
---|---|
Salesforce(세일즈포스) Current Geolocation Component (0) | 2022.04.16 |
Salesforce Admin Exam (1) | 2022.04.10 |
Salesforce 관리자에게 필요한 11가지 엑셀(Excel) 팁 (0) | 2022.04.10 |
Salesforce' Global Picklist 설명 (0) | 2022.04.10 |