- PR -

NumberFormatException が非チェック例外なのはなぜ?

投稿者投稿内容
DaikiRyuto
大ベテラン
会議室デビュー日: 2002/07/23
投稿数: 200
投稿日時: 2003-11-17 19:16
引用:

catch できない?
どういう事でしょう?


すいません、変な言い草でした。
NumberFormatExceptionの例外検出が行われていなくても
コンパイルが通ってしまう、ということを言いたかっただけです。
でくのぼう
大ベテラン
会議室デビュー日: 2003/10/06
投稿数: 162
投稿日時: 2003-11-17 21:12
うーん、なるほど。

どうにも早とちりしていたようです。
要点ズレてました、大変失礼しました。

さてさて、Java言語仕様の例外に関しての記述を読み返してみました。
http://www.y-adagio.com/public/standards/tr_javalang/11.doc.htm

「11.2.2 実行時例外を検査しない理由」
というところを見ていただくと、
今回の疑問にリンクするであろう事が書かれていますね。

引用:

11.2.2 実行時例外を検査しない理由

実行時例外のクラス(runtime exception classes,RuntimeException
及びそのサブクラス)は,コンパイル時に検査されない。その理由は,
そのような例外を宣言させることは,Javaプログラムの正当性の確立を
大して援助しない,とJava設計者が判断したためである。
Java言語の演算及び構文の多くは,実行時例外を生じることができる。
Javaコンパイラが利用できる情報及びコンパイラが実行する分析の
レベルは,通常,たとえJavaプログラマには明白であるとしても,
それらの実行時例外が起こり得ないと証明するためには十分でない。
そのような例外クラスの宣言を要求することは,単にJavaプログラマを
苛立たせるだけだと考えられる。

例えば,あるコードが,その構造によって,決して空参照を
含むことがない循環的なデータ構造を実装したとする。
このとき,プログラマは,NullPointerExceptionは,
決して起こらないと確信できる。しかし,コンパイラがそれを
証明するのは,困難であろう。データ構造のそのような大域的な
特性を確立するために必要な定理証明技術は,
このJava言語規定の範囲を超える。



さて、これを読み返したところで私の目からウロコが落ちました。
というのも私もKeisukeさんが言うように

引用:

非チェック例外とは、「発生しないことを保証できるコーディングが可能な例外」



と考えていたのですが「発生しないことを保証できない」からこそ
「非チェック」にしていた、と現実は正反対だったのです・・・。

それゆえに ubibon さんが言うように

引用:

非チェック例外を catch するのは、よほどのことがない限りすべきではない



という部分には、まったく賛同していたのですが
このような理由で非チェック例外が定義されたのなら
別に catch しても良いじゃないか、と考えてしまいました。

// 調べるうちに考えが揺れてきています。

よろしければ、非チェック例外を catch する事の善し悪し、
および、その理由といった、皆様方の見解を教えて頂ければ幸いです。


>DaikiRyutoさん
あ、なるほど了解です。


[ メッセージ編集済み 編集者: でくのぼう 編集日時 2003-11-17 21:12 ]
おばけ
ぬし
会議室デビュー日: 2002/11/14
投稿数: 609
お住まい・勤務地: 東京都江東区
投稿日時: 2003-11-17 22:42
引用:

フォーマット検査を行わない値をいきなり数値変換するから「例外」が起こり得るわけ


確かに。

引用:

NumberFormatExdeption を検査代わりに使うのは一種のSyntax Sugarと言えるかも。


よくやりますねえ。
プロパティファイルで数値を設定する場合、Property#getStringはStringを返すので、これをInteger#parseIntしてNumberFormatExceptionをキャッチします。
まあ、本来はよくないですよね。

それよりも、Character#isDigitを使うとすると、Stringをいちいちcharの配列にしてループで回してやらないといけないのでしょうか?みなさんはどうやって判定されてるんですか?
さくらば
大ベテラン
会議室デビュー日: 2002/11/12
投稿数: 145
投稿日時: 2003-11-18 04:58
こんにちは、さくらばです。

引用:

おばけさんの書き込み (2003-11-17 22:42) より:

それよりも、Character#isDigitを使うとすると、Stringをいちいちcharの配列にしてループで回してやらないといけないのでしょうか?みなさんはどうやって判定されてるんですか?



こんな感じで

コード:

String str = ......

str.matches("\\d+");



もちろん java.util.regex.Pattern と java.util.regex.Matcher 使ってもいいです。

[ メッセージ編集済み 編集者: さくらば 編集日時 2003-11-18 04:57 ]
Wata
ぬし
会議室デビュー日: 2003/05/17
投稿数: 279
投稿日時: 2003-11-18 12:06
Wataです。
単純なforループや正規表現でのチェックでは値域のチェック(int値の上限・下限など)
はできません。そのような入力があった場合はやはりNumberFormatExceptionが発生します。
下手に自分でチェックを行うよりも、try-catchを行う方が確実でよいのでは?
おばけ
ぬし
会議室デビュー日: 2002/11/14
投稿数: 609
お住まい・勤務地: 東京都江東区
投稿日時: 2003-11-18 12:48
引用:

さくらばさんの書き込み (2003-11-18 04:58) より:
コード:
    String str = ......

    str.matches("\d+");




なるほど、JDK1.4からは正規表現が使えますね。

ただ、Wataさんのおっしゃるように値域のチェックの問題は残ってしまいますね。
そうなると、やっぱりいきなりInteger#parseIntして例外をcatchするのが楽なのですかね。どうもこのスレッドの最初の議論からはしっくり来ない結論のような気がしますが。。。設計者に意図した使い方をを聞いてみたいですなぁ。

ともあれ、おかげさまでなんとなく分かりました。これからもInteger#parseIntしてcatchすることにします。
ありがとうございました。
Wata
ぬし
会議室デビュー日: 2003/05/17
投稿数: 279
投稿日時: 2003-11-18 12:54
Wataです。でくのぼうさんの下記の書き込みについて...
引用:

でくのぼうさんの書き込み (2003-11-17 21:12) より:
さてさて、Java言語仕様の例外に関しての記述を読み返してみました。
http://www.y-adagio.com/public/standards/tr_javalang/11.doc.htm

(略)

さて、これを読み返したところで私の目からウロコが落ちました。
というのも私もKeisukeさんが言うように

引用:

非チェック例外とは、「発生しないことを保証できるコーディングが可能な例外」



と考えていたのですが「発生しないことを保証できない」からこそ
「非チェック」にしていた、と現実は正反対だったのです・・・。



でくのぼうさんのこの言語使用に対する解釈はまったく逆だと思います。
これはコンパイラが実行時例外を検査しない理由について説明しているので、
プログラマにとって『発生しないことを保証することが可能』で
あるが、コンパイラにとって『発生しないことを保証できない』
から、コンパイラは検査しない。」
という内容だと、私は解釈しています。

なので、「発生しないことを保証できるコーディングが可能な例外」が
RuntimeExceptionのサブクラスとして定義されるべきであり、プログラマは
「発生しないことを保証するコーディング」をすることが強く求められると思います。
逆に、プログラマにとって、発生しないことを保証することが、不可能・困難・極度に非効率的
な例外はRuntimeExceptionのサブクラスにするべきでないといえると思います。
でくのぼう
大ベテラン
会議室デビュー日: 2003/10/06
投稿数: 162
投稿日時: 2003-11-18 13:32
主語を混乱していたわけですね。
確かに、コンパイラが「保証できない」だけでした。

スキルアップ/キャリアアップ(JOB@IT)