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

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

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

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

6回答

10298閲覧

例外処理を利用する意味、メリットについて質問です。

kon_ta

総合スコア81

Java

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

2グッド

3クリップ

投稿2016/06/21 14:30

例外処理を利用する意味、メリットについての質問です。

言語に依存しないと思いますが、例としてPythonの例外処理でゼロ除算の例外処理を行うZeroDivisionErrorなどがあると思います。
標準入力put()で分母の数を与えるといったプログラムがあった場合、例外処理のように当該部分をtryで囲んで・・・
といった処理ではなく、if文で条件判定をし、入力されたプログラムが0であればエラーコードをprint()で表示して
強制終了など、例外処理に似たことはできると思います。

特に独自に作成した例外などは以下のように
//////////////////////////////////////////////////
{文字列に大文字が含まれていたら例外処理をおこなうプログラム (参考):入門Python3 P134}

class UppercaseException(Exception):
pass

・・・
・・・・・
・・・・・・

words = ['eeenie','meenie',''MO]
for word in words:
if word.isupper():
raise UppercaseException(word)

///////////////////////////////////////////////////

結局if文を用いて例外条件に当てはまる場合、raiseで例外を呼び出すという処理を行っています。
以上のことから単純にif文で当該条件の場合エラーコード生成などの何らかの処理を行えばいいのであって、
例外処理を用いる意味、メリットは少ないのかなと思ってしまいます。

現状if文で書くよりかはコードが理解しやすいといったことはあるのかなと思いますが、
それ以外でメリット、またこの場合if文では対応できない、というのはあるのでしょうか?

どなたか知識のある方、回答の方よろしくお願い致します。

Lhankor_Mhy, matobaa👍を押しています

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

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

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

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

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

guest

回答6

0

ベストアンサー

例外がないC言語を書いていると、例外が無性に恋しくなるときがあるのですが・・・。ということで、主に例外がないC言語と比較しながら述べます。

例外を一切発生させないようにプログラミングできるかというと、できます。というよりもそれができなければ例外がないC言語でプログラミングはできないことになってしまいます。では、例外はあるとなぜ便利なのか、どういうふうに使えば良いのかを述べていきます。

###落ちたところや原因がわかる

ほとんどのプログラミング言語で0除算はしてはいけないことになっています。例外があるプログらミグ言語では0除算に対する例外を発生させるでしょう。では、C言語ではどうかというと、SIGFPEシグナルを発行してアプリ全体が落ちます。通常、そのとき、どの関数のどの行で何が起きたのかと情報は一切表示されません。(シグナルはわかりますが、原因が0除算であるかどうかまではわかりません)
※ C言語の0除算時の動作は未定義となっており、処理系によっては異なります。UNIX/Linuxの処理系ではシグナル発行する場合が多いです。

もし、例外であれば、キャッチしていない場合は同じようにアプリが落ちますが、デフォルト状態でどの場所でどのような例外が発生したかを表示します。これだけでも後から原因を調査する大きな手がかりになりますので、問題解決がスムーズに行えるようになります。

###自動で大域脱出

メモリ不足やファイルオープン失敗などその場ですぐに解決できないような問題が発生するときがあります。完全にアプリを落としてしまうと言うのもありますが、中には今の処理をキャンセルして、しばらく待ってからリトライするとか、別処理を走らせるとかが考えられます。

そこで問題となるのは、複数の関数呼び出しや入れ子のfor文の深いところで発生した時です。途中で失敗したら、最初の呼び出しや最初のforの外側に戻りたい場合があるでしょう。例外があれば、途中でキャッチしない限り、どこまでも自動で遡ります。リトライなどの処理をしたいところでキャッチして、例外に即した処理を追加すればうまくいくでしょう。

では、C言語だとどうするかというと、途中の関数呼び出しをすっ飛ばすためにlongjmpを使います。このlongjmp、使い勝手が良いとはとても言えません。また、for文の深いところから脱出するには悪名高きgotoを使います。gotoをなぜ避けるべきかはいろいろなところで述べられていますが、下手なgotoはスパゲッティ化を招きます。
※ gotoは書いてはいけないと言われていますが、例外の代わりに(というより例外がないので)gotoを使うことは正しい使用方法の一つです。ただ、それなりの上級者ではないと難しいため、初心者には安易に使うなと言った方がいいということです。

###問題が起こるかも知れないがわかる

C言語では、ファイルオープンや書き込みに成功したかどうかを確認するのはプログラマーの仕事です。それを忘れてしまうと突然アプリが落ちるなど、想定外のバグが発生します。

Javaではファイルオープン時などにIOExceptionが発生する可能性があります。これは必ずキャッチするか、メソッドにthrows IOExceptionをつけて例外が発生するかもと知らせる必要があります。このようにして、プログラマーに例外の処理を強制させ、失敗時の処理を忘れる等の不具合の原因を排除します。(この機能はJavaぐらいで、採用している言語は少ないです。また、Javaでも全ての例外が必須になっているわけではありません。)


さて、例外を使うよりはif文で分岐させたほうが・・・とありますが、まさしくその通りです。例外は本来、おきてはいけないことであり、そもそも発生させるべきではありません。また、例外処理自体がかなり重い処理のため、安易に頼るでべきでもありません。0かも知れない変数を除算する前に0になっていないかをチェックすること悪いことでも何でもなく、例外があるからしなくてもいいとか、例外に頼らなければならないということではありません。

しかし、IO関係は実際に読み書きなどしないとできるかどうかはわからないなど、事前にチェックすることは不可能な例外があります。また、本来はバグ以外で起きないよう動作、例えば配列でインデックスを越えてアクセス等は、事前チェックが冗長になってしまいます。そのようなときは、例外に頼ることは良い方法だと思います。あまり具体的な例を出せないで申し訳ないのですが、ここら辺は他のプログラム(入門書とかの無意味なサンプルではなく)がどのように書いているかとか見たり、自分で書いていく内に感覚が掴めるのではないかと思っています。

投稿2016/06/21 21:13

raccy

総合スコア21733

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

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

0

すべての条件を事前にチェックして、例外やエラーが発生しないようにすることは面倒さをいとわなければおおむね可能です。
ただ、ファイル書き込み中にディスク不足で書けないようにならないかなどを事前にチェックするのは無理、もしくは可能な場合も面倒だしOS依存になります。これはちょっと極端すぎる例かもしれませんが、これに近い例は数多くあるかと。
0除算くらいは事前チェックで良いかと思います。

あと、エラーを事前に発見した場合、どうするかですね。メッセージを出してプログラム終了なら簡単ですが、ライブラリのように、呼び出し元にエラーを伝えることが必要な場合など、さらに面倒です。

投稿2016/06/21 15:16

otn

総合スコア84421

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

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

0

if文で分けると業務ロジックとエラー処理が混ざってしまうというデメリットがあると個人的には思ってます。

あとPythonは、よく分かりませんが例外はチェーン出来るというメリットがあります。
メソッド内でエラー完結できればいいですが、呼び出し元にエラーとして返さなければいけない場合、本来の値とは違うエラーを表す方法を何かしら返さねばならず大変面倒なことになりますよ。

投稿2016/06/21 14:52

Mr_Roboto

総合スコア2208

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

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

0

0 での割り算なら、割り算の実行前に 0 かどうかの判定をすることは可能です。
でも実数の割り算での場合、 0 で比較をしてチェックする事はあまり有効ではありません。
大きな数を 0 ではない小さな数で割り算をしたら、オーバーフローすることがあるからです。

整数での演算でも 大きな数同士の掛け算、足し算などで、オーバーフローが発生することもあります。
こういったものをすべて計算前にすべてコードで明示的にチェックしていたら、単純計算でも大変な行数になってしまいます。

C++ の場合ですが、 整数演算のオーバーフローの扱いの例があります。
オーバーフローのチェック http://ufcpp.net/study/csharp/sp_checked.html#float

例外という機構をつかうことで、チェックコードの省略と、エラー発生時の処理を統一的に扱えます。

投稿2016/06/21 22:13

katoy

総合スコア22324

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

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

0

Integer.parseIntが投げるNumberFormatExceptionは引数が数字以外というだけではなく、intで表せる範囲外のものになっても発生します。これを正規表現などで判別するのは困難です。またIOException系は、コード上で回避出来ないものも多数在ります。

投稿2016/06/21 14:44

swordone

総合スコア20649

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

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

0

私は基本C/C++ でやっています。
C/C++ は (特にCは) if文でチェックするので、不要に感じていましたが、
考え方を変えると「かなり必要」です。

関数 ( Javaでいうメソッド ) なら、戻り値が true ( または データ ) ならOK,
それ以外なら なんらかのエラー とできます。

では、クラスのコンストラクタ内でなんらかのエラー ( メモリ確保や、ファイルを開く等の処理で。 ) が起こった場合はどうなるでしょう。

例外処理を設けないと、

オブジェクト生成 -> メソッドで何らかの処理

と行ってしまいます。

オブジェクトがない状態なのに動かそうとしています。

存在しないものを「存在することを証明せよ」というのと同じことです。

(コンストラクタから)例外を投げて、例外処理を設けると、

オブジェクト生成 -> (例外が飛ばされたので) オブジェクト生成失敗 -> catchのところに -> メソッドのところにはいかないため、処理がされない

となります。

つまり、コンストラクタ用のチェック構文って感じですね。

投稿2016/06/22 07:04

BeatStar

総合スコア4958

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問