【JAVA】初心者バグをなくそう PART4 -例外処理-

例外処理は、コーディングの中で一番重要な処理だと考えています。

不具合があったときの最後の砦。
だからこそしっかりとした設計・しっかりとしたプログラミングが必要です。

でも現実は、面倒くさい思うのか、はたまた難しいと思われているのか
結構軽視されることの多い例外処理。

これはJAVAの経験年数を積んだ人でもしっかりとした
設計・コーディングができている人が少ないです。


逆に言うと例外処理を極めることで人よりも1歩進むことができます。


今回は初心者向けということで設計というよりいつものように
実際にあった不具合を参考にコーディングレベルでの
注意点について書きたいと思います。


■ログの嵐


とある場所で例外が発生しました。
むむ!?なぜだか、異常にログ出力が多い。
ソースコードを追ってみると。。。

下記のようなコードが書かれていました。

public void process(String id) {
	try  {
		try {
			Integer iId = new Integer(id);
			int cnt = iId.intValue();
		} catch (NumberFormatException ex) {
			ex.printStackTrace();
			throw new SystemException(ex);
		}

		残りの処理・・・

	} catch (Exception ex) {
	 ex.printStackTrace();
	}
}


サンプルのため簡単に記述しなおしていますが、基本のフォーマットは同じです。

お分かりかと思いますが、
『ex.printStackTrace()』という文が7行目と14行目で2回出現しています。
そのためエラー時の情報が重複してログ出力されていました。


これは、正しく例外処理を理解していないといことです。

正しい例の一つは、
public void process(String id) {
	try  {
		Integer iId = new Integer(id);
		int cnt = iId.intValue();
		残りの処理・・・
	} catch (NumberFormatException ex) {
		System.err.println("引数idが数字に変換可能な値ではありません");
		ex.printStackTrace();
	} catch (RuntimeException ex) {
		System.err.println("想定外の例外が発生しました");
		ex.printStackTrace();
	}

となります。


だいぶ違いがあるかと思いますが、なぜこうなるのかは別途お話したいと思います。
それまでにご自身で理由を考えてもらえればと思います。



■データベースに接続できない;;


これまた、とある場所でSQLの実行ができないとのエラーが発生しました。

再現性を確認するために同じ操作を繰り返しおこなっていると・・・
『データーベースへの接続数がいっぱいでこれ以上は無理!』というエラーが発生しだしました。
それ以降はずっとその状態。

それは下のようなソースでした。


public static String selectName(String pkey) {
	// DBへ接続
	// getConnection()で正常にコネクションが取れるものとします。
	Connection con = getConnection(); 

	// 入力された主キーが数値以外の場合エラーを返す。
	try  {
		Integer iPkey = new Integer(pkey);
	} catch (NumberFormatException ex) {
		throw new SystemException("引数idが数字ではありません");
	}

	try {
		検索の処理・・・
	} catch (SQLException e) {
		throw new SystemException("データベース操作中にエラーが発生", e);
	} finally {
		con.close();
	}
}



上記のソースを見てすぐに気がつくかもしれませんが、
8行目で変数 pkey に数値以外が入力されていた場合は 10行目の例外処理は行われますが、
それより後ろに書かれている 18行目の con.close();の部分は実行されることはありません。



必ず後始末が必要な場合、何があっても後始末をしなければいけません。

正解は。
public static String selectName(String pkey) {
	// DBコネクション
	Connection con = null;

	// 入力された主キーが数値以外の場合エラーを返す。
	try  {
		Integer iPkey = new Integer(pkey);
		
     	// getConnection()で正常にコネクションが取れるものとします。
        con = 	getConnection(); 

		検索の処理・・・

	} catch (NumberFormatException ex) {
		throw new SystemException("引数idが数字ではありません");
	} catch (SQLException e) {
		throw new SystemException("データベース操作中にエラーが発生", e);
	} finally {
        if (con != null) {
    		con.close();
        }
	}
}


ありえない!と思うかもしれませんが、実際にあった話です。
もしかしたら数日に及ぶ残業・徹夜などが続き正常にコーディングができなかったのかもしれません。

しかしながら、このレベルの不具合は絶対に発生させてはいけないことです。
頭がモウロウとしていても、指が覚えている。そんなレベルになってほしいと思います。

しっかりとコネクションを閉じることができれば問題ありません。
この手のバグは一回埋め込まれてしまうとなかなか発見することができないため
コーディングの最中から常に注意を払いたいですね。

■今日のポイントひらめき


例外処理をする時、場所をしっかりと考えよう。
例外処理は必ず行われるように注意をしよう

この例外処理については、考え方も難しいため改めてきちっとした 記事を書こうと考えています。
とりあえず、今回は上記2つのポイントを抑えておいてくださいね。
タグ:java 初心者


参考になりましたらクリックしていただけると励みになります。



posted by てる。 at 00:16 | Comment(0) | TrackBack(0) | 【JAVA】初心者バグをなくそう | このブログの読者になる | 更新情報をチェックする
×

この広告は180日以上新しい記事の投稿がないブログに表示されております。