はじめに
Apexは、Salesforce上でビジネスロジックを実装できる、Javaに似たプログラミング言語です。
今回取り上げる安全なナビゲーション演算子は、
null 参照の明示的な順次チェックの代わりに、安全なナビゲーション演算子 (?.) を使用します。この演算子は、null 値を操作しようとする式を除外し、NullPointerException を発生させずに null を返します。
チェーン式の左側が null に評価される場合、右側は評価されません。
Apex 開発者ガイドより
と説明されています。
C#やKotlinほか、Apex以外で開発されていた方にはお馴染み、そしてWinter’21リリース以降Apexで開発を始められた方もご存知の機能だと思います。
※Winter’21以前からApexで開発されていた方は知らない、ということではありませんよ。
みなさん使ってますか?
あらためて
そもそもnullを許容するのかしないのか、許容しなければ NullPointerException(以降ヌルポと表現)は発生しない訳ですが、Apexで扱う型はnullを保持できます。
ですから、ヌルポに出会うことはよくあるのですが、それを回避するのに、安全なナビゲーション演算子 (?.)を使うのは、1つの対策になります。
ヌルポに出会うことがよくあってはいけませんね…
しかし、開発している時、テストしている時は気付くことができず、本番運用後に気付かされたという経験をされてる方も多いのでは。
本番運用後に気付かされることもあってはいけませんけどね…
Javaは?
冒頭で「C#やKotlinほか」という書き方をしました。
Javaに似たプログラミング言語Apexの話をしているのに、Javaが出てきてませんね。
Javaでは、仕様の変更(演算子での実現)では無く、仕組みの追加(クラスでの実現)で、ヌルポに対処する安全なコードを書くことになる為、演算子を使わない(使えない)からというのが理由です。
Javaでは、java.util.Optionalクラスを使うのですが、説明は割愛します。
利用イメージ
基本的な利用イメージ
会社>部署>従業員というオブジェクト構成があり、従業員オブジェクトから従業員名を取得したい。
この処理をこう記述できるとします。
1 |
String userName = company.getDivision().getEmployee().getUserName: |
会社オブジェクトがnullだったら?
部署オブジェクトがnullだったら?
従業員オブジェクトがnullだったら?
なんとなく「テストしている時は気付くことができず、本番運用後に気付かされた…」、この状況に該当してしまいそうです。
nullをチェックする記述にしましょう。
1 2 3 4 5 6 7 8 9 10 |
String userName; if (company != null) { division = company.getDivision(): if (division != null) { employee = division.getEmployee(); if (employee != null) { userName = employee.getUserName; } } } |
フツーにこんな感じでしょう。
このくらいならまだ読めますが、あと1つ2つネストが増えただけで読みづらさが増しますし、条件判断後の処理が増えても読みづらさが増してしまいます。
安全なナビゲーション演算子を使った記述にしましょう。
1 |
String userName = company?.getDivision()?.getEmployee()?.getUserName: |
あくまで1つの例ですが、スッキリした感じになりました。
適当なところで分割した方が、更にスッキリ読み易くなるかもしれません。
ただ、この安全なナビゲーション演算子を知ってるかどうかで、随分と違いが出てくることは間違いないですよね。
SOQLを使った利用イメージ
SOQLの結果のサイズを確認するという記述。
よく見ますし、よく書きました。
1 2 3 4 5 |
String accountName; List<Account> accountList = [SELECT Name FROM Account WHERE Id = :accountId]; if (accountList.size() != 0) { accountName = accountList[0].Name; } |
安全なナビゲーション演算子を使った記述にしましょう。
1 |
String accountName = [SELECT Name FROM Account WHERE Id = :accountId]?.Name; |
後続の処理で何をするか次第だったりしますが、このように記述することができます。
ということくらいは覚えておきたいですね。
その他の利用イメージ
その他については、Apex 開発者ガイドを参照して下さい。
おわりに
安全なナビゲーション演算子について紹介しました。
きっかけは
「素直に機能紹介します。」
では無く、
「2020年秋公開のWinter’21新機能、今更だけど知ってるよね。ちゃんとリリースチェックしてるよね。」
です。
いろいろ知らないまま置いていかれないようにしてないとダメですよって。
自社のSalesforceエンジニアはもちろん、これを見たSalesforceエンジニアの一助になればいいかな、と思ってます。