こちらのブログ記事を読んでびっくりしたのと、「try catchでオーバーフローがキャッチされなくてハマった」という話をどっかで聞いたので
検証と対策を記載してみようかと思います。
検証するコード
class Sample_171211{ public static void main(String[] args) { int i = 1; try{ for (; i >= 0; i++) { } System.out.println(i); } catch (Exception e){ System.out.println("Exceptionがキャッチされました。"); } } }
キャッチされないのは分かっていたのですが、一応try catchも書きました。
▼実行してみた結果
本当ニコンパイルトオッタヨー実行デキチャッタヨー…
コンパイルが通って、普通に実行できた理由はこちらのブログ記事を参照ください。
対策方法
Java8から導入されたMathクラスを使うとちゃんとスローしてくれるようになります。
今回はincrementExactというメソッドがあるようなので使ってみました。
以下に修正したコードを記載します。
class Sample_171211{ public static void main(String[] args) { int i = 1; try{ for (; i >= 0; i++) { Math.incrementExact(i); } System.out.println(i); } catch (Exception e){ System.out.println("Exceptionがキャッチされました。"); } } }
forの中に
Math.incrementExact(i);
の1行を追加しました。
incrementExactメソッドは「引数を1だけ増分して返し、結果がintをオーバーフローした場合は例外をスローする」ということをやってくれるメソッドとなります。
▼再度実行してみた結果
「Exceptionがキャッチされました。」と表示されました。
Mathクラスには他にも色々なメソッドがあるので、こちらに目を通しておくと今後幸せに開発を行えるかも…。
まとめ
・オーバーフローするコードでもコンパイルは通るし普通に実行もでき、Exceptionは出ない
・Java8から導入されたMathクラスを使い、対象のメソッドを呼び出すとオーバーフローをスローしてくれる
・Mathクラスには他にも色々なメソッドがある
Javaで開発を行っていてオーバーフローの問題にあたったことはないのですが
こういうこともあると勉強になりました。