さまざまな例外種別のキャッチ
前のレッスンの例では、catch ブロックで具体的な例外種別を使用しました。すべての例で汎用的な Exception 種別だけをキャッチすれば、あらゆる例外種別をキャッチすることも可能です。たとえば、SObjectException を発生させ、catch ステートメントの引数に Exception 種別を指定した次の例を実行してみます。SObjectException は catch ブロックでキャッチされます。
または、複数の catch ブロックを使用して、例外種別ごとに 1 つの catch ブロックを指定し、最後の catch ブロックで汎用的な Exception 種別をキャッチすることもできます。次の例を見てください。3 つの catch ブロックがあります。
すでに説明したとおり、実行される catch ブロックは 1 つのみで、残りの catch ブロックはスキップされます。この例は前の例と似ていますが、catch ブロックの数が少し増えています。このスニペットを実行すると、行 Double inventory = m.Total_Inventory__c; で SObjectException が発生します。すべての catch ブロックが指定された順序で、発生した例外と catch ブロックの引数に指定された例外種別が一致するまで調べられます。
- 最初の catch ブロック引数は DmlException 種別で、発生した例外 (SObjectException) と一致しません。
- 2 つ目の catch ブロックの引数は SObjectException 種別で、発生した例外と一致するため、このブロックが実行され、メッセージ「SObjectException caught: SObject row was retrieved via SOQL without querying the requested field: Merchandise__c.Total_Inventory__c」がデバッグログに書き出されます。
- 最後の catch ブロックは、catch ブロックが 1 つすでに実行されているため、無視されます。
最後の catch ブロックは、どの例外種別でも、つまり、前の catch ブロックでキャッチされなかったどの例外でもキャッチするため、便利です。たとえば、上記のコードを NullPointerException が発生するように変更すると、この例外は最後の catch ブロックでキャッチされます。変更した次の例を実行します。デバッグメッセージ「Exception caught: Attempt to de-reference a null object」が表示されます。