NullPointerExceptionを出したら負けかなと思っている

 私はプログラマーとして、NullPointerExceptionを出したら負けかなと思っています。

 例外というのはアプリケーション例外とシステム例外というのに大別できると思います(別の用語を使うほうが適切なのかはわかりません)。ここでいうアプリケーション例外というのは、例えば金額が入力されるべきところに数字以外の文字が入れられたというような場合に発生する「ユーザに由来する」ような例外です。システム例外というのは、例えばソケットを使って通信をしていたときに回線が切れたというような場合に発生する「ユーザの操作に寄らず、ハードやソフトが健全な状態であれば本来発生し得ない」ような例外です。

 アプリケーション例外は、概して捕捉されて然るべきものでしょう。システム例外ももちろん捕捉されるべきでしょうが、OutOfMemoryなどのシステム例外は捕捉してもどうしようもありません。

 ここでNullPointerExceptionについて考えて見ましょう。NullPointerExceptionは、何故起こるのでしょうか? NullPointerExceptionとは、本来値が入っているべき変数に値が入っていなかったために起こる例外です。では、何故、値が入っていないなどという自体が起こるのでしょうか?

 理由のひとつは、例えばユーザが入力すべき値を入力しなかったなどのアプリケーション例外として起こったというものです。この場合は、この例外は捕捉されて然るべき処理が行われるべきです。そのまま投げっぱなしなんてしたら負けです。値を入力してくださいなどのメッセージを出力するべきでしょう。

 他の理由としては、別のシステム例外によって変数に値が設定される処理が実行されなかったために、Nullになってしまったということが考えられます。これは明らかにシステム例外の処理の失敗です。先ほどOutOfMemoryだったら捕捉してもどうしようもないと述べましたが、それだったらNullPointerExceptionを投げっぱなしにするまえにそちらの例外を投げっぱなしにするべきでしょう。そうすれば、メモリを増強するなり何なり対策が打てるからです。

 つまり、まとめるとNullPointerExceptionは、例外処理のほころびと私は考えています。そしてこの記事のカテゴリにSeasarを含めたのは、SeasarではよくNullPointerExceptionが出るのです。原因のほとんどは、私の設定ミスです。しかし、そのミスの箇所を探すのが凄く大変なのです。何故か? それはNullPointerExceptionが投げっぱなしだからです。それは使い方によってはすべての項目を設定する必要はないでしょうから、Nullというのは許されて然るべき状態なのかもしれません。しかしコードの自動生成などを行っているソリューションだということは、それだけで内部エラーが追いにくいのです。せめて何を参照しようとしたらNullだったかぐらいの報告はできないものなのでしょうか?

 特に新人なんかに使わせると「何が悪いのかがわかりません」と言われ「これだったら使わないほうが楽」なんてなってしまいます。本当に使いやすいものというのは、設定ファイルがいらないというのもそうかもしれませんが、ダメだったときの挙動がいかに親切かなのではないでしょうか。

 私は設定ファイルの記述ミスが親切にレポートされるもののほうが、設定ファイルはいらないけどミスのレポートがあやふやなものよりは使いたいと思いますね。

2006/6/8 追記

 具体的には、S2JSF のバージョンを 1.0.8 から 1.0.14 に上げようとしてライブラリを入れ替えているときに起こりました。どちらのバージョンも S2JSF Blank からライブラリを持ってきています。ですから、s2-framework と s2-extension のバージョンも変えようとしたわけです。にもかかわらず、はじめ dicon にまったく手を入れませんでした。この時点でのエラーもよくわからなかったのですが、dicon を入れ替えてエラーの内容が変わったものの、それもよくわからない。それこそが、出所不明のNullPointerException だったわけです。