[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 1471] Re: assertion 、事前 条件の例外スロー方法



高橋(徹)です。

> 前橋です。
:
> 今はもう辿れませんが、昔 Sun の Web サイトにあったJava programmer's
> FAQ には、Assert の実装例が載っていて、それでは RuntimeException を
> 投げていました。
うーん、やっぱりRuntimeExceptionなんですねぇ。。。確かにそのスレッドは
RuntimeExceptionで終了するのですが、他のスレッド群は生き続けています。
しかも、RuntimeException時にstackTraceがコンソールに表示されずに消えて
しまうことがよくあり、ときどき困ったなぁと思うことがあります。
#RuntimeExceptionをスローする際、ログにメッセージを書いてくれれば
#まだましなんだけど・・・ 

> 例えば、年齢を引数として受け取るメソッドで、マイナスの値がやってきたら
> そりゃ上位のルーチンが決定的に「バグっている」わけで、そんな状態から
> 処理を続けてもろくな結果が出るわきゃなかろう、と思うからです。
「達人プログラマー」の22節死んだプログラムは嘘をつかない
 ヒント32:早めにクラッシュさせること
ですね。ろくな結果がでないだけでなく、バグがある場所がどこか分かり
にくくしてしまいますね。

> だから、assertでは、RuntimeExceptionを投げるどころか、スタックトレースを
> 吐いてSystem.exit()しちゃってもいいぐらいだと思います。JavaOSで動いてる
> とかでなければ。
開発・デバッグ時はそうなんですが、運用中はたとえバグが原因であっても
止まってほしくないのです。生き続けられる限りは生き続けて欲しい。。。
その代わり、詳細な情報をログに吐いておかないと、後でバグを究明できな
くなりますが。

> もちろん、呼び出され側である程度の処理をしないと引数の妥当性が
> わからない、だから、呼び出し側では、とりあえず呼んでみて
> IllegalArgumentExceptionをcatchする、というケースは話が別ですが。
うーん、これはまずいです。エラーチェックはやっぱり呼び出し側で
行わないと。。。妥当性をどうしても相手側に判断してもらわなければ
ならない場合は、妥当性チェックメソッドを用意すべきと思います。

昔例外を覚えたての頃、mainの引数チェックが面倒だから
 public static void main(String[] args) {
   try {
     // args[0]やargs[1]といった感じで直接アクセス
   } catch (ArrayIndexOutOfBounds e) {
     // 引数の使い方を表示してデフォルト値をセット
   }
   :
なんてコード書いてしまったこともありますが、、、例外の使い方としては
まずかったです。

> Javaの場合、基本的に領域破壊はないので、「あっちの方はバグってる
> けど、こっちはまだ元気」ということを期待してもよいのかもしれません。
これはC/Javaというよりか、モジュールの作り方・独立性によると思います。
他のクラス(インスタンス)を利用しまくっていれば、壊れたインスタンスを
呼び出してしまうわけですし(壊れたインスタンスからも呼ばれるなぁ。。。)

> また、C の場合、例えば戻り値でエラーステータスを返しても、
> 呼び出し側でチェックをさぼっている可能性がかなり高く、致命的な
> バグの時に悠長にステータスなんぞ返すよりもとっとと殺してしまった
> 方が確実にバグを捕捉できる、という事情もあるわけですが、Javaなら、
> 例外はたとえチェックをさぼっても最終的に捕捉できるので、安全かも
> しれません。
ずいぶん安全になったとは言えますね。

> でも、
> 
>   try {
>       処理;
>   } catch (Exception ex) {
>       ;
>   }
> 
> こんなことされてちゃ困るなあ... そのぐらいならいっそ、Errorを
> 投げる方がより確実かも。
Javaの入門書や雑誌にこんなコードがあふれているのが問題・・・
それを見て、平気でこんなコードを書くようになってしまう。
ちょっと面白いWebページがありました。
「勉強用のサンプルは低レベルなものが多い」
http://www.st.rim.or.jp/~k-kazuma/SD/SD201.html
エラー処理の話しではないですが、開発環境や雑誌のサンプルをまねてしまう
問題が載っています。

> それに、Javaだと、動的なクラスロードがあるわけで、
:
> じゃあ、「Graphicsクラスの何かのメソッド」で「ちゃんと」引数
> チェックを行なって、例外を投げて... も、処理が戻るのはその怪しげな
> アプレットまでなわけで、やっぱりいまいちです。どうせなら、
> そのアプレットのpaint()メソッドの呼び出し元まで戻って、
> そんな腐れたアプレットはとっととアンロードしちまって、「なかったこと」
> にしたいですよね。
フレームワーク側にどこまで強度さ(頑健さ)を求めるかにもよりますが。
危ないプログラムは排除するような仕組みはおもしろそうです。
次世代の言語ではこのような機構があるといいな。。。
#Unsafe Programming Exception: このクラスはフレームワークを
#誤って使っています。アンロードされました。


======------======------======
Toru Takahashi,  TOSHIBA Corps. KOMUKAI Works
(office)tooru6.takahashi@xxxxxxxxxxxxx
(private)torutk@xxxxxxxxxxx
         http://www.alles.or.jp/~torutk/