この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

Newer Version Available

This content describes an older version of this product. View Latest

安全なナビゲーション演算子

null 参照の明示的な順次チェックの代わりに、安全なナビゲーション演算子 (?.) を使用します。この演算子は、null 値を操作しようとする式を除外し、NullPointerException を発生させずに null を返します。

チェーン式の左側が null に評価される場合、右側は評価されません。安全なナビゲーション演算子 (?.) は、メソッド、変数、プロパティチェーニングで使用します。評価されない式の部分には、変数参照、メソッド参照、または配列式などがあります。

すべての Apex 型は暗黙的に 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;
表 1. 安全なナビゲーション演算子の使用事例
可能な使用事例 詳細情報
メソッド/変数/パラメータチェーン aObject?.aMethod(); 最上位のステートメントとして使用できます。
キャスト内など、括弧の使用。 ((T)a1?.b1)?.c1() この演算子は、最初の閉じ括弧までメソッドチェーンをスキップします。括弧の後に演算子を追加することで、このコードは式全体を保護します。演算子を括弧の後以外の場所で使用すると、キャスト式全体が保護されません。たとえば、次の動作を考えます。
1//Incorrect use of safe navigation operator
2((T)a1?.b1).c1()
上記は、次のステートメントと同等です。
1T ref = null;
2if (a1 != null) {
3ref = (T)a1.b1;
4}
5result = ref.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 に評価されます。その動作は次と同等です。
1List<Contact> contacts = [SELECT LastName FROM Contact]; 
2String s; 
3if (contacts.size() == 0) { 
4   s = null; // New behavior when using Safe Navigation. Earlier, this would throw an exception. } 
5else if (contacts.size() == 1) { 
6   s = contacts.get(0).LastName; } 
7else { // contacts.size() > 1 throw new QueryException(...); }
場合によっては、安全なナビゲーション演算子を使用できません。このような場合に演算子を使用しようとすると、コンパイル中にエラーが発生します。
  • ドットが含まれる種別や静的式。次に例を示します。
    • 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');

    ただし、sObject の addError() で演算子を使用することはできます。

    メモ