JavaやC#のループ内におけるbreak文とcontinue文は、次の意味を持ちます。

・break:ループから(ひとつ外側へ)脱出する。
・continue:ループの先頭に戻る。

まれに見られるバグとして、breakと書くべき場所がcontinueになっていることがあります。
その逆もあります。

テストフェーズでこのバグを特定するとき、breakとcontinueの意味を意識しながら追わないと見逃してしまう場合があります。

複雑なIF条件式の中にbreakやcontinueが記述されているとテストケースから抜けてしまう可能性があるので、プログラミング時にしっかりチェックすることが大切です。

にほんブログ村 IT技術ブログへ
にほんブログ村
switch文(Java、C#、C)は複数の処理を分岐するときに使用します。
注意しなければいけないのが、分岐処理はif文のように{}で囲む必要はなく、breakが現れるとswitch文が終了するということです。
つまり、breakが呼ばれなければ、勝手に次のcaseラベルの中に侵入してしまうのです。

以下の例は、「case 0:」にbreakがないために「case 1:」に侵入してしまう例です。
[NG例][Java]
public static void main(String[] args) {
int n = 0;

switch (n) {
case 0:
System.out.println("ケース0。");
// break文を記述していない。
case 1:
System.out.println("ケース1。");
break;
case 2:
System.out.println("ケース2。");
break;
default:
System.out.println("デフォルト。");
}
}

[出力結果]
ケース0。
ケース1。

break忘れのバグを防ぐには、case処理の最後には必ずbreakを書くという癖をつけることが大切です。

にほんブログ村 IT技術ブログへ
にほんブログ村
ソースコードの記述を間違うと、バグの発生につながる可能性が高くなります。

本テーマでは、「コンパイルは成功するが、記述が誤っていたため、プログラムが正しく動作しない」ケースを扱いたいと思います。

このケースは、コンパイルエラーよりもたちが悪い問題です。
コンパイルエラーはコンパイラがエラーの内容を知らせてくれますが、コンパイラが成功したモジュールのバグを見つけ出すには、十分なテストを行わなければいけないからです。

本テーマの事例から、バグのパターンを意識してプログラミングすることにより、記述ミスから発生するバグを削減することが可能だと思います。

にほんブログ村 IT技術ブログへ
にほんブログ村
Javaではfinal宣言されたメソッドはオーバーライドできません。
コンパイルエラーとなります。
[NG例][Java]
public class Sample1 {
public final void Test() {
}
}

public class Sample2 extends Sample1{
// final宣言されているためオーバーライドできない。
public void Test() {
}
}

オーバーライドのJavaとC#の違いについて補足します。
C#はデフォルト(修飾子がついていない)のメソッドはオーバーライドできない仕様になっています。
Javaはデフォルトのメソッドはオーバーライドできます。
オーバーライドに関するデフォルトの仕様が違うことがお分かりいただけると思います。

整理しますと、
Javaでは「デフォルトではオーバーライドできるが、final宣言してオーバーライドできないようにする」という考え方ですが、C#では「デフォルトではオーバーライドできないが、virtual宣言してオーバーライドできるようにする」という考え方です。

にほんブログ村 IT技術ブログへ
にほんブログ村
戻り値のあるメソッドの処理で、return文が抜けているとコンパイルエラーとなります。

[OK例][Java]
public int max (int a, int b) {
int max;
if (a >= b) {
max = a;
}
else {
max = b;
}

// return文が記述されていない。
}

[OK例][Java]
public int max (int a, int b) {
int max;
if (a >= b) {
max = a;
}
else {
max = b;
}

return max;
}

メソッドの宣言部を書いたら、中身を書く前に、nullや0などの仮の値を返すreturn文を書く癖をつけておくと、コンパイルエラーが発生しないので、わずらわしくありません。

にほんブログ村 IT技術ブログへ
にほんブログ村
変数をメソッドのように()をつけて呼び出してしまうことがあります。

著者が経験したミスとして、Javaの配列のメンバ変数「length」を「length()」と記述してしまいました。
[NG例][Java]
public static void main (String[] args) {
int[] array = new int[] {1, 2, 3};
int length = array.length();
}

[OK例][Java]
public static void main (String[] args) {
int[] array = new int[] {1, 2, 3};
int length = array.length;
}


にほんブログ村 IT技術ブログへ
にほんブログ村
JavaとC#では文字列(string)は「"(ダブルクォート)」で囲い、文字型(char)では「'(シングルクォート)」で囲います。
stringなのに「'」を使用してしまうと、コンパイルエラーが発生します。

JavaScriptの文字列は「"」と「'」のどちらも使用できます。
言語の違いによる使い分けには注意が必要です。

にほんブログ村 IT技術ブログへ
にほんブログ村
インスタンス化できないクラスとして、
 ・抽象クラス(abstract宣言されたクラス)
 ・publicコンストラクタがないクラス
があります。
これらのクラスを強引にnewを使ってインスタンス化しようとするとコンパイルエラーとなります。

例をあげると、JavaのCalendarクラスは抽象クラスになっているためnewを使用するとエラーとなります。
[NG例][Java]
Calendar now = new Calendar();

インスタンスを取得するには、getInstanceメソッドを使用します。
[OK例][Java]
Calendar now = Calendar.getInstance();


にほんブログ村 IT技術ブログへ
にほんブログ村
JavaとC#ではIF文の条件式の中は、boolean(bool)型にしなければなりません。
以下のコードはコンパイルエラーとなります。
int n = 0;
if (n) {

}

ところでC言語の場合はどうでしょうか。
C言語はIF文の条件式はint型でもポインタ型でも許されているので、上記コードはコンパイルできます。
0ならtrue。それ以外の場合はfalseとして判断されます。

C言語では許可されていた仕様がJavaとC#では禁止されているので使い分けには注意が必要です。

にほんブログ村 IT技術ブログへ
にほんブログ村
継承が禁止されているクラスを継承するとコンパイルエラーとなります。
Javaでは、クラスにfinalがついていた場合、継承ができません。

[NG例][Java]
public final class Sample1 {

}

// Sample1クラスは継承できない。
public class Sample2 : Sample1 {

}

標準クラスを継承して、新しいクラスを作ろうと構想を練って、いざコーディングしてみると、継承したクラスがfinal宣言されていたので失敗した。ということは何度か経験しています。
あらかじめドキュメント等でクラスの仕様を確認すべきでした。

VBの場合はNotInheritable、C#の場合はsealedがついているクラスは継承できません。

にほんブログ村 IT技術ブログへ
にほんブログ村