質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

Q&A

解決済

1回答

2641閲覧

例外処理(TRY CATCH と throws)について

Dash_003

総合スコア27

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

0グッド

0クリップ

投稿2020/02/04 08:45

編集2020/02/05 01:09

Javaにおける例外処理について、普段特に考えることもなく
「とにかく例外が発生しうるコードはtry{}内に書いて、発生した場合の処理はcatch{}に書く!」
という認識で行っていました。

throwsというものも知ってはいるものの、try{}catch{}で良いのでは?と思ってしまいます。
ただ、本来他から呼び出されるメソッドであればthrowsを使い、単体で動くメソッドはtry{}catch{}を
使うべきなのかな?という疑問もあります。

そもそも例外処理についての認識が合っているかや、try{}catch{}とthrowsの使い分けの考え方が合っているか教えていただきたいです!

#【追記】
分かりにくい質問文ですが、聞きたい事、疑問に思っている事は
『例外はすべてtry{}catch{}で処理できるのにthrowsを使う場面はあるのか?』
『一種の条件分岐のように使用してよいものなのか?』
ということです。

例えば入力チェックを行う際、以下のようにStringからintへ変換する場合には
入力された値が数値であればエラーは発生しませんが、文字列などであれば型変換の
エラーが発生します。

//呼び出し元クラス public class Text { public void inputText () { /* * inputstreamなどを使用し、ユーザーに文字や数字などを入力させる */ String str = "入力された値"; boolean isNumFlag = util.isNum(str); //例外が発生しうる部分 if (isNumFlag == true) { system.out.println("入力された値は数字です"); } else { system.out.println("入力された値は数字ではありません"); } } } //呼び出されるクラス、メソッド public class util { public static boolean isNum (String str) { int Num = Integer.parseInt(str); //例外が発生しうる部分 } }

この場合だと、呼び出されるメソッドについてはthrowsで例外を投げて、そのうえで呼び出し元クラスでtry{}catch{}で動作を分岐させれば良いと考えています。
ただその場合だとif文は使用せず、実質try{}catch{}が条件分岐のような扱いになるのが気になる所です。こういう使い方をしても問題がない、むしろこう使うべきものであるなら今のやり方で安心ができますが。

//呼び出し元クラス public class Text { public void inputText () { /* * inputstreamなどを使用し、ユーザーに文字や数字などを入力させる */ String str = "入力された値";  try { boolean isNumFlag = util.isNum(str); //例外が発生しうる部分 system.out.println("入力された値は数字です");  } catch(〇〇Exception e) {   system.out.println("入力された値は数字ではありません");  } } //呼び出されるクラス、メソッド public class util { public static boolean isNum (String str) throws 〇〇Exception { int Num = Integer.parseInt(str); //例外が発生しうる部分    return true; } }

個人的には呼び出し元のクラスはできるだけごちゃごちゃさせたくない、深いネストになる可能性があるコードは
書きたくないという気持ちがあるので

//呼び出し元クラス public class Text { public void inputText () { /* * inputstreamなどを使用し、ユーザーに文字や数字などを入力させる */ String str = "入力された値"; boolean isNumFlag = util.isNum(str); //例外が発生しうる部分 if (isNumFlag == true) { system.out.println("入力された値は数字です"); } else { system.out.println("入力された値は数字ではありません"); } } } //呼び出されるクラス、メソッド public class util { public static boolean isNum (String str) { try { int Num = Integer.parseInt(str); //例外が発生しうる部分 return true; } catch (〇〇Exception e) {  return false; } }

このような書き方の方が好きなのですが、好みの問題なのですかね?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/02/04 10:14

どこで例外を処理するかの設計
m.ts10806

2020/02/04 11:35

自身でコードはどれくらい書いて確かめたのでしょうか。
Dash_003

2020/02/05 00:23

『どこで処理するかの設計』 →それを考えたときに、「他から呼び出されて使うメソッドについてはthrowsで他に例外を投げる。単体で動作するメソッドについてはtry{}catch{}で自己処理を行う。」と認識していたのですが正しいのか確認するために質問しました。 『自身でコードはどれくらい書いて確かめたのでしょうか。』 →確かめるというのがどういったことを指しているのかわかりませんが、普段コードを書く時にはすべてtry{}catch{}で例外を自己処理しており、ひとまずサーバー側のエラーがユーザーに表示されるような状況にはならない作りにはしています。また、特にそのせいで困るということもありませんでした。 ただ、本来ならtry{}catch{}を乱用するのではなくthrowsと合わせて適切に使い分けるべきなのかなと思い質問をしました。
m.ts10806

2020/02/05 00:30

困ってないならそれでいいのでは。
guest

回答1

0

ベストアンサー

『例外はすべてtry{}catch{}で処理できるのにthrowsを使う場面はあるのか?』

try~catchとthrowsは、そもそも別の仕組みなので、これを同一で話そうとしている時点で
理解が不足していると感じます。

作成するメソッドの例外に何かあるのを通知するための仕組みが、throws
使うメソッドの例外に対応するのが、try~catch

です。

『一種の条件分岐のように使用してよいものなのか?』

一種の条件分岐ではありますが、たぶん現時点では、その考えは危険だと思います。


例外は処理ができない場合の通知方法です。
戻り値で処理が続行できないことを通知することもありますが、これは設計指針で決めます。

例にあるisNumですが、この処理を読んだ場合、以下の3通りの結果になります。

true
false
例外発生

isNumが数値かどうか判定するのであれば、例外を発生させる意味は無いと多くの設計者は考えると思います。
つまり、上記の場合、例外をcatchして、falseを返すようにすると思います。
例でいう後者の書き方。

では、引数2つを受け取って割り算の答えを返すメソッドは、どうするか?
戻り値は数値になるので、処理の異常を戻り値で通知することはできません。
※ラッパークラスを導入して、nullの場合、失敗みたいな設計もある

この時、なにも考えずに除算を実行して

ArithmeticException を出すのか、
入力チェックをしてIlligasArgumentException をthrowするのか。
または、独自例外を作成するのか。(DivideByZeroExceptionみたいな)

は、設計の話だったりします。(例としてダサイけど。許して)

使う側は、この処理で例外がthrowされること。
なんらかの対応をする必要があることが、わかります。


try、catchは、例外処理と正常系処理のブロックを分けて記述するのに便利なものです。

個人的には呼び出し元のクラスはできるだけごちゃごちゃさせたくない

が、根底にあります。

処理結果を戻り値でチェックするようにすると、つどつど成功失敗を判定する必要があります。...

ret = xxxx(xxxx); if( ret.IsSuccess()) { ret2 = yyyy(xxxx); if ( ret2.IsSuccess() ) { ret3 = xxxxx(); if (ret3.IsSuccess()) (省略) } }

こんなネストにしたくないので、
例外処理は、例外が発生しなければ正常。っていう思想で
以下のように記述できるのがメリットです。

try { // このブロックは例外が発生しなければ正常終了 ret = xxxx(xxxx); ret2 = yyyy(xxxx); ret3 = xxxxx(); return new Result(ret.xxxx, ret2.xxxxx, ret3.xxxx); }cathc(Ret1Exception e) { throw new HogehogeExceipton(e); }cathc(Ret2Exception e) { throw new HogehogeExceipton(e); }

例外をまるめる場合、tryの中にtryを書くよりも別メソッドを定義したほうがよいです(できるならですが)

/// 例外を丸める場合は別メソッドを用意する private Ret3 xxxxx() { try { //なにか例外が発生するコード return hogehoge; } catch (Ret3Exception e) { return fugafuga; } }

このへんの例外の考え方は、”契約による設計、Design by Contract”
で、調べるといろいろ出てくるので読んでみてください。

投稿2020/02/05 03:45

momon-ga

総合スコア4820

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Dash_003

2020/02/05 04:30

丁寧な回答ありがとうございます。 throwsはあくまでそのメソッドを使う人に「例外が発生しうるメソッドであること」を知らせる為に記述するものであり、呼び出し元で処理をするのかそもそも呼び出されるメソッド側で例外を対処しthrowsしないようにするかは設計次第、といった理解で間違っていないでしょうか? とにかく一度”契約による設計、Design by Contract”を調べて読んでみたいと思います。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問