安全なナビゲーション演算子
null 参照の明示的な順次チェックの代わりに、安全なナビゲーション演算子 (?.) を使用します。この演算子は、null 値を操作しようとする式を除外し、NullPointerException を発生させずに null を返します。
チェーン式の左側が null に評価される場合、右側は評価されません。安全なナビゲーション演算子 (?.) は、メソッド、変数、プロパティチェーニングで使用します。評価されない式の部分には、変数参照、メソッド参照、または配列式などがあります。
例
- 次の例では、まず a を評価し、a が null の場合に null を返します。それ以外の場合、戻り値は a.b になります。
1a?.b // Evaluates to: a == null ? null : a.b - 次の例では、a[x] が null に評価される場合に null を返します。a[x] が null に評価されず、aMethod() で null が返される場合、この式で NullPointerException がスローされます。
1a[x]?.aMethod().aField // Evaluates to null if a[x] == null - 次の例では、a[x].aMethod() が null に評価される場合に null を返します。
1a[x].aMethod()?.aField - 次の式では、安全なナビゲーション演算子が式で使用されているかどうかに関係なく、式の型が同じであることを示します。
1Integer x = anObject?.anIntegerField; // The expression is of type Integer because the field is of type Integer - 次の例では、null をチェックするコードのブロックを置き換える 1 つのステートメントを示します。
1// Previous code checking for nulls 2String profileUrl = null; 3if (user.getProfileUrl() != null) { 4 profileUrl = user.getProfileUrl().toExternalForm(); 5}1// New code using the safe navigation operator 2String profileUrl = user.getProfileUrl()?.toExternalForm(); - この例では、安全なナビゲーション演算子を使用する 1 行の SOQL クエリを示します。
1// Previous code checking for nulls 2results = [SELECT Name FROM Account WHERE Id = :accId]; 3if (results.size() == 0) { // Account was deleted 4 return null; 5} 6return results[0].Name;1// New code using the safe navigation operator 2return [SELECT Name FROM Account WHERE Id = :accId]?.Name;
| 可能な使用事例 | 例 | 詳細情報 |
|---|---|---|
| メソッド、変数、またはパラメーターチェーン | aObject?.aMethod(); | 最上位のステートメントとして使用できます。 |
| キャスト内など、括弧の使用。 | ((T)a1?.b1)?.c1() | この演算子は、最初の閉じ括弧までメソッドチェーンをスキップします。括弧の後に演算子を追加することで、このコードは式全体を保護します。演算子を括弧の後以外の場所で使用すると、キャスト式全体が保護されません。たとえば、次の動作を考えます。 |
| sObject チェーニング | String s = contact.Account?.BillingCity; | 関係が null の場合、sObject 式は null に評価されます。その動作は String s = contact.Account.BillingCity と同等です。 |
| SOQL クエリ | String s = [SELECT LastName FROM Contact]?.LastName; |
SOQL クエリでオブジェクトが返されない場合、式は null に評価されます。その動作は次と同等です。
|
場合によっては、安全なナビゲーション演算子を使用できません。このような場合に演算子を使用しようとすると、コンパイル中にエラーが発生します。
- ドットが含まれる種別や静的式。次に例を示します。
- Namespaces
- {Namespace}.{Class}
- Trigger.new
- Flow.interview.{flowName}
- {Type}.class
- 静的変数アクセス、メソッドコール、式。次に例を示します。
- AClass.AStaticMethodCall()
- AClass.AStaticVariable
- String.format('{0}', 'hello world')
- Page.{pageName}
- 割り当て可能な式。次に例を示します。
- foo?.bar = 42;
- ++foo?.bar;
- SOQL バインド式。次に例を示します。
1class X { public String query = 'xyz';} 2X x = new X(); 3List<Account> accounts = [SELECT Name FROM Account WHERE Name = :X?.query] 4List<List<SObject>> moreAccounts = [FIND :X?.query IN ALL FIELDS 5 RETURNING Account(Name)]; - sObject スカラー項目に addError() が含まれる。次に例を示します。
1Contact c; 2c.LastName?.addError('The field must have a value');