はじめに
コーディングにおいては、実行時に見つかる些細なバグの対応がつきものです。
バグの対応を素早く行うことができれば、コーディングも早く行うことができるようになります。
今回の記事では、例を挙げて、バグ対応の一般的な手順を説明しようと思います。
手順を大まかに書くと、以下のような手順になります。
- バグの発生箇所を特定する
- バグの原因を確認して取り除く
バグの見つけ方と直し方の例
今回のサンプルプログラム
今回は、例として、「0~9の範囲の値を実行する度にランダムに表示する」というプログラムをJavaでコーディングしながら説明していきます。
以下のソースコードにはバグがあり、実行すると「NullPointerException」という例外が出力され、処理が途中で止まってしまいます。
【サンプルコード1】
・NullPoTest.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import java.util.Random; public class NullPoTest { public static void main(String[] args) { // Randomクラスのオブジェクトを生成する(参照先を割り当てる) Random random = null; // ランダムな値を生成する(0~9) int outputValue = random.nextInt(10); // 生成した値を表示する System.out.println(outputValue); } } |
【実行結果】
1 2 |
Exception in thread "main" java.lang.NullPointerException at NullPoTest.main(NullPoTest.java:11) |
以降で、バグの原因を特定して、バグを取り除いてみます。
バグの発生箇所の特定
まずは、「バグの発生箇所を特定する」の手順を実施していきます。
実装や環境を問わずに実施できる方法としては、「デバッグ表示の行を入れ込み、どこまで通っているのかを確認する」という方法です。
今回の例では、この方法で「Random random = null;」まで処理が通っており、「int outputValue = random.nextInt(10);」が通っていないことを確認することができます。
また、今回の例では実施していませんが、デバッグ表示の行の中で変数の値を出力し、変数がどのような値を取っているのかを確認するのも良い方法です。
【サンプルコード2】
・NullPoTest.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import java.util.Random; public class NullPoTest { public static void main(String[] args) { System.out.println("チェックポイント1"); // Randomクラスのオブジェクトを生成する(参照先を割り当てる) Random random = null; System.out.println("チェックポイント2"); // ランダムな値を生成する(0~9) int outputValue = random.nextInt(10); System.out.println("チェックポイント3"); // 生成した値を表示する System.out.println(outputValue); } } |
【実行結果】
1 2 3 4 |
チェックポイント1 チェックポイント2 Exception in thread "main" java.lang.NullPointerException at NullPoTest.main(NullPoTest.java:14) |
なお、言語や環境、実装は問いますが、以下のような方法も有効です。
- スタックトレースに表示される行数を手掛かりにする(実は、今回の例では、エラーメッセージ中に「NullPoTest.java:11」と出ているので、それを手掛かりにすることもできます)
- IDE(Eclipse等)のデバッグ機能を用いる
- ソースコード中でエラーメッセージの文言を作っている場合は、その文言でソースコード中を検索する
バグの原因の確認と修正
バグの発生箇所を特定できたので、次は「バグの原因を確認して取り除く」を実施していきます。
「NullPointerException」をWebで調べてみると「参照先が無い(nullを示している)参照型変数を参照した場合に発生する」という類のことが出てくると思います。
オブジェクト指向言語に慣れていないと説明だけ読んでもわからないかもしれませんが、Webの記事の中にサンプルコードが併記されていることも多く、それを読むと理解の助けになると思います。
今回のソースコードでは、「Random random = null;」という箇所で参照型変数「random」にnullを代入しているのが原因のため、ここを修正し、新たな参照先を割り当ててそれを代入することで、バグを解消することができます。
これはJavaの言語がエラーメッセージを出している場合の調査方法ですが、他のバグの場合は調べ方が変わってきます。
例えば、出力される値が期待する値と異なる場合は、計算がどこで間違っているのかをソースコードを追ったり変数の値をデバッグ表示でこまめに出力したりしながら確認していくことになります。
また、ソースコード中でエラーメッセージの文言を作っていてそれが出力された場合は、そのエラーメッセージが何を示しているのかを仕様書等を参考に確認していくことになります。
知識や経験が少ないと、調べても原因の特定に至らない場合があります。
類似処理を別のソースコードで行っている場合は、その類似処理と見比べることで原因を特定できる場合もあるので、それを試してみましょう。
それでもわからない場合は、無理をせずに他の人に聞いてみると良いでしょう。既に、発生箇所を特定し、原因調査も途中までは済ませているため、あまり時間を取らせずにスムーズに回答を得ることができます。
【サンプルコード3】
・NullPoTest.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import java.util.Random; public class NullPoTest { public static void main(String[] args) { // Randomクラスのオブジェクトを生成する(参照先を割り当てる) Random random = new Random(); // ランダムな値を生成する(0~9) int outputValue = random.nextInt(10); // 生成した値を表示する System.out.println(outputValue); } } |
【実行結果】
1 |
5 |
あとがき
プログラミングにはバグがつきものですが、このように、発生箇所を特定して、原因を突き止めて、修正する、という手順を踏むと、バグに悩まされることは少なくなります。
私が研修でプログラミングを教えたり、実務で相談に乗ったりする際も、この手順を教えたり指示したりすることが度々あり、多くの場合はそれだけで自力でバグの原因を突き止めて修正できるようになるので、この手順を意識していなかった方は頭の片隅に置いておくと良いでしょう。
株式会社サイゼントでは、即戦力のJavaプログラマーを育てるための書籍「絶対にJavaプログラマーになりたい人へ」をKindleで販売しています。
同じく、Spring Frameworkについてきめ細かく解説した別冊も販売中です。
また、上記の書籍をテキストとして用いたプログラミングスクール「サイゼントアカデミー」も開校しています。
このスクールは、受託開発事業・SES事業である弊社が、新入社員向けの研修で培ったノウハウを詰め込んだものです。
ご興味がある方は、上記画像から個別ページにアクセスしてみてください!
コメント