一般的なErrorと違ってプログラム実行中における想定内のError(Exception例外
)が発生する箇所によく使われるのがtry
やthrow
、finally
です。今回はそれぞれの使い方をまとめて行きたいと思います。中でも良く使われるのがtry catch
でtry内部で発生する全ての例外に処理を実行することができます。
##try on
void main() {
String hoge = 'hogehoge';
try {
print(int.parse(hoge)); // hogeをint型に変換させようとしている
} on FormatException { // on内部でFormatExceptioを指定して対処
print('int型でなくString型ですよ!');
}
} // => intでなくStringですよ!
// try {
// 例外が発生する可能性のある処理
// } on 例外名 {
// 指定した例外が発生した時の処理
// }
##try catch
void main() {
String hoge = 'hogehoge';
try {
print(int.parse(hoge));
} catch (e) { // catch内部引数にすべての例外であるオブジェクトを指定
print(e); // e => Exceptionの型情報をprintで取得
print('try内部で例外発生');
}
} // => FormatException: hogehoge, try内部で例外発生
// ^
// try{
// 例外が発生する可能性のある処理
// }catch(e){
// 指定した例外が発生した時の処理
// }
##try on catch
void main() {
String hoge = 'hogehoge';
try {
print(int.parse(hoge));
} on FormatException {
print('例外発生'); // 最初の例外チェック、ここで指定されていた例外があれば処理を実行
} catch (e) {
print(e); // 指定した例外がなければこちらのcatch内部で処理を実行
print('try内部で例外発生');
}
} // => 例外発生
// try{
// 例外が発生する可能性のある処理
// } on 例外名 {
// 指定した例外が発生した時の処理
// }catch(e){
// 指定した例外が発生した時の処理
// }
##throw
void main() {
int hoge = 500;
try {
if (hoge > 100) {
throw '100より大きい'; //try内部のif文によく使われる
}
print(hoge); //throwが実行されるとtry内部での処理を中断してcatch内部の処理に移る
} catch (e) {
print(e); //throwで指定したError文を(e)で出力
print('throwが発火して例外発生');
}
} // => 100より大きい, throwが発火して例外発生
// try {
// if () {
// throw 'Error文を指定';
// }
// } catch (e) {
// print(e) //throwで指定したError文が出力
// 指定した例外が発生した時の処理
// }
##finally
void main() {
String hoge = 'hogehoge';
try {
print(int.parse(hoge));
} catch (e) {
print(e);
print('try内部で例外発生');
} finally {
print('例外の発生の有無に関わらず、最後に処理を実行');
}
} // => FormatException: hogehoge, try内部で例外発生, 例外の発生の有無に関わらず、最後に処理を実行
// ^
// try {
// 例外が発生する可能性のある処理
// } catch (e) {
// 指定した例外が発生した時の処理
// } finally {
// 例外処理の最後に実行したい処理
// }
##rethrow
main() {
void hogeFunc() {
try {
throw Exception('例外発生'); // throw Exceptionで意図的に例外を発生
} on Exception catch (e) {
print(e); // catch内部の引数でException型(e)を指定
rethrow; // rethrowでtry catch finallyの外に例外を弾く(関数の外でcatch)
} finally {
// finally内部は例外の有無にかかわらず実行される、省略可。
print('最後に必ず実行');
}
}
try {
hogeFunc();
} catch (e, h) {
// 型指定無しのcatchは、何型かわからない例外全てキャッチする
// catchに仮引数を2つ指定すると、2つ目はStackTraceオブジェクトが入る
print(h);
}
}
// => Exception: 例外発生,
// 最後に必ず実行,
// #0 main.hogeFunc,
// #1 main,
// #2 _delayEntrypointInvocation.<anonymous closure>,
// #3 _RawReceivePortImpl._handleMessage