プログラミング作法 - Java 編


■内容

Top

プログラミング作法

クイズ

  1. 配列要素に値を設定します。 (解答)
    1. for (int theElementIndex = 0; theElementIndex < numberOfElements; theElementIndex++) {
    2. elementArray[theElementIndex] = theElementIndex;
    3. }

  2. 値c にエラーがあるかどうかを検査し、その結果を boolean 型で戻します。 (解答)
    1. if (check(c)) ...

  3. blockId がbottomBlockId を下回っていないか、topBlockId 以上でない。 (解答)
    1. if (!(blockId < bottomBlockId) || !(blockId >= topBlockId))
    2. ...

  4. x に マスクをかけて、それが BITS と等しい。 (解答)
    1. int x = ...;
    2. if (x & MASK == BITS)
    3. ...

  5. ... (解答)
    1. x += (xp = (2 * k < (n-m) ? c[k+1] : d[k--]));

  6. bitoff を 8 で割った余り分だけ右シフトします。 (解答)
    1. subkey = subkey >> (bitoff - ((bitoff >> 3) << 3));

  7. str 配列の 2 つの要素を空白にします。 (解答)
    1. str[i++] = str[i++] = ' ';

  8. 2月の最大日の検査をします。(実行結果エラーです) (解答)
    1. boolean = true;
    2. if (month == FEB) {
    3. if (year%4 == 0)
    4. if (day > 29)
    5. legal = false;
    6. else
    7. if (day > 28)
    8. legal = false;
    9. }

  9. 配列のすべての要素を 1 にします。 (解答)
    1. int i = 0;
    2. while (i <= n-1)
    3. a[i++] = 1;
    1. for (int i = 0; i < n; )
    2. a[i++] = 1;
    1. for (int i = n; --i >= 0; )
    2. a[i] = 1;

  10. うるう年を判定します。 (解答)
    1. boolean leap = false;
    2. if (y % 4 == 0)
    3. if (y % 100 != 0)
    4. leap = true;
    5. else if (y % 400 == 0)
    6. leap = true;

  11. ヒストグラムを書きます。 (解答)
    1. fac = lim / 20; /* スケールファクターをセット */
    2. if (fac < 1)
    3. fac = 1;
    4. /* ヒストグラムを生成 */
    5. for (int i = 0, col = 0; i < 27; i++, j++) {
    6. col += 3;
    7. k = 21 - (let[i] / fac);
    8. star = (let[i] == 0) ? ' ' : '*';
    9. for (int j = k; j < 22; j++)
    10. dwar(j, col, star);
    11. }
    12. draw(23, 2, ' '); /* x軸のラベル */
    13. for (int i = 'A'; i <= 'Z'; i++)
    14. drawLabel(i);

  12. 大文字かどうかを検査します。 (解答)
    1. char c = ...;
    2. if (c >= 65 && c <= 90)

  13. 要素数がわからない配列要素の平均値を出します。 (解答)
    1. int arg(int[] a) {
    2. int sum = 0;
    3. for (int i = 0; i < a.length; i++) {
    4. sum += a[i];
    5. }
    6. return sum / a.length;
    7. }

  14. 型の違う値を使います。(コンパイル・エラーになります) (解答)
    1. int i1, i2, i3;
    2. long l1;
    3. ...
    4. i3 = (i1 > 10) ? i2 : l1;

  15. 引数で指定された回数分、ループします。 (解答)
    1. void func(long n) {
    2. for (int i = 0; i < n; i++) {
    3. ...
    4. }
    5. }

  16. 値を検査します。 (解答)
    1. if (var1 == 0) {
    2. ...
    3. } else if (0 < var1) {
    4. ...
    5. }

  17. 値を検査します。 (解答)
    1. switch (var1) {
    2. case 0:
    3. ...
    4. break;
    5. case 1:
    6. ...
    7. break;
    8. }

  18. 配列の要素数分ループします。 (解答)
    1. int[] a = ...;
    2. for (int i = 0; i != a.length; i++) {
    3. ...
    4. }

  19. (解答)
    1. int i;
    2. for (i = 0; i < MAX; i++) {
    3. data[i] = i;
    4. }
    5. if (min > max) {
    6. i = max;
    7. max = min;
    8. min = i;
    9. }

  20. (解答)
    1. for (int i = 0; i < MAX; j++) {
    2. ...
    3. i++;
    4. }

  21. (解答)
    1. for (i = 0; ループの継続条件1; i++) {
    2. ...
    3. if (終了条件1) {
    4. break;
    5. }
    6. if (終了条件2) {
    7. break;
    8. }
    9. if (継続条件2) {
    10. continue;
    11. }
    12. ...
    13. }

  22. var1 の値により、sig に設定します。(結果誤り) (解答)
    1. switch (var1) {
    2. case 0:
    3. sig = ZERO;
    4. case 1:
    5. sig = PLUS;
    6. default:
    7. sig = MINUS;
    8. }
Top

Eclipse とプラグイン

Top

CheckStyle プラグイン

Top
プラグインのインストールと設定
Top
使用例

  1. CheckStyle を使用する前に、まず、Eclipse のコード・フォーマッターを使って、コードのスタイルを整えます。
    [エディッターで右クリック] - [ソース] - [フォーマット]
    

  2. プロジェクトの CheckStyle を有効にすると、つぎの図のように、行の背景色や、行番号のところにレンズ・アイコンが出て、スタイルに違反している行を表示します。
    
     checkstyle01
     図 ソース上のメッセージ
    
Top

FindBungs プラグイン

Top
プラグインのインストールと設定
Top
使用例

  1. "FindBugsSample01.java"

    1. public class FindBugsSample01 {
    2. public static Counter count = new Counter();
    3. public static void main(String[] args) {
    4. String aString = "bob";
    5. aString.replace('b', 'p');
    6. if (aString.equals("pop")) {
    7. System.out.println("true");
    8. }
    9. String bString = null;
    10. if (isBound() && isBound()) {
    11. bString = " Hello! ";
    12. }
    13. aString = bString.trim();
    14. System.out.println("true");
    15. if (aString == bString) {
    16. System.out.println("same string");
    17. }
    18. }
    19. public static boolean isBound() {
    20. return count.countup() == 10;
    21. }
    22. }
    23. class Counter {
    24. int count;
    25. public int countup() {
    26. return count++;
    27. }
    28. public boolean isUnBound() {
    29. return !new FindBugsSample01().isBound();
    30. }
    31. }
    
     findbugs01
     図 ソース上のメッセージ
    
    
     findbugs02
     図 「問題」タグのリスト
    

  2. ソースの「警告」マークや「問題タグ」のエントリーを右クリックして、「Show Bug Details」を選択すると、つぎのような「問題」の詳細が表示されます。
    
     findbugs03
     図 「問題」の詳細
    
Top

Metrics プラグイン

Top
プラグインのインストールと設定
Top
使用例

  1. "FindBugsSample01.java"で、メソッドの行数がしきい値を超えるものには、メッセージが出ます。
    
     metrics01
     図 ソース上のメッセージ
    

  2. Metrics プラグインの測定結果のレポートは、以下の手順で、指定したディレクトリーに HTML ファイルとして出力されます。指定より、CSV ファイルのレポートも出力することができます。

  3. [対象プロジェクトを右クリック] - [エクスポートを選択] - [その他] - [Metricsを選択] - [Export Directoryにレポートの出力先を記入] - [OK]
    
     metrics02
     図 ホームページ
    
    
     metrics04
     図 パッケージ内行数
    
    
     metrics03
     図 パッケージ内サイクロマチック数
    
    
     metrics05
     図 パッケージ内サイクロマチック数の詳細
    
Top

クイズ解答

  1. ローカル変数には短い名前を使おう
    1. for (int i = 0; i < elem.length; i++) {
    2. elem[i] = i;
    3. }

  2. メソッドには能動的な名前を使おう
    1. if (hasError(c)) ...

  3. 自然な形の式を使おう
    1. if (!((blockId >= bottomBlockId) && (blockId < topBlockId)))
    2. ...

  4. かっこを使ってあいまいさを解消しよう
    1. int x = ...;
    2. if ((x & MASK) == BITS)
    3. ...

  5. 複雑な式は分割しよう
    1. if (2*k < n-m) {
    2. xp = c[k+1];
    3. } else {
    4. xp = d[k--];
    5. }
    6. x += xp;

  6. 明快に書こう
    1. subkey >>= bitoff & 0x7;

  7. 副作用に注意しよう
    1. str[i++] = ' ';
    2. str[i++] = ' ';

  8. インデントとプレースのスタイルを統一しよう
    1. boolean = true;
    2. if (month == FEB) {
    3. if (year%4 == 0) {
    4. if (day > 29) {
    5. legal = false;
    6. }
    7. } else if (day > 28) {
    8. legal = false;
    9. }
    10. }

  9. 慣用句によって一貫性を確保しよう
    1. for (int i = 0; i < a.length; i++) {
    2. a[i] = 1;
    3. }

  10. 多分岐の判定にはelse-ifを使おう
    1. boolean leap = false;
    2. if (y % 400 == 0) {
    3. leap = true;
    4. } else if(y % 100 == 0) {
    5. /* DO NOTHING */
    6. } else if(y % 4 == 0) {
    7. leap = true;
    8. } else {
    9. /* DO NOTHING */
    10. }
    ただ、この程度であれば、つぎのように論理演算子を使ったほうがわかりやすい場合もあります。
    1. boolean leap = false;
    2. if ((y % 400 == 0) || ((y % 100 != 0) && (y % 4 == 0))) {
    3. leap = true;
    4. }
    さらに、boolean 型の変数に値を代入しているのであれば、つぎのようにすることもできます。
    1. boolean leap = (y % 400 == 0) || ((y % 100 != 0) && (y % 4 == 0));

  11. マジックナンバーには名前をつけよう
    1. final int MINROW = 1; /* 上端 */
    2. final int MINCOL = 1; /* 左端 */
    3. final int MAXROW = 24; /* 下端(<=) */
    4. final int MAXCOL = 80; /* 右端(<=) */
    5. final int LABELROW = 1; /* ラベル位置 */
    6. final int NLET = 1; /* アルファベットの数 */
    7. final int HEIGHT = MAXROW - 4; /* バーの高さ */
    8. final int WIDTH = (MAXCOL-1)/NLET; /* バーの幅 */
    9. fac = (lim + HEIGHT - 1) / HEIGHT; /* スケールファクターをセット */
    10. if (fac < 1)
    11. fac = 1;
    12. /* ヒストグラムを生成 */
    13. for (int i = 0; i < NLET; i++) {
    14. if (let[i] == 0)
    15. continue;
    16. for (int j = HEIGHT - let[i]/fac; j++)
    17. dwar(j+1+LABELROW, (i+1)*WIDTH, '*');
    18. }
    19. draw(MAXROW-1, MINCOL+1, ' '); /* x軸のラベル */
    20. for (int i = 'A'; i <= 'Z'; i++)
    21. drawLabel(i);

  12. 整数ではなく文字定数を使おう
    1. char c = ...;
    2. if (c >= 'A' && c <= 'Z')
    ただし、上記もお勧めできません。以下のようにすべきです。

    システムの用意しているライブラリーを使おう

    1. char c = ...;
    2. Character.isUpperCase(c)

  13. 事前と事後の状態をテストしよう
    1. int arg(double[] a) {
    2. int sum = 0;
    3. for (int i = 0; i < a.length; i++) {
    4. sum += a[i];
    5. }
    6. return a.length <= 0 ? 0 : sum / a.length;
    7. }
    または、Exception をスローします。
    1. int arg(double[] a) throws Exception {
    2. if (a.length <= 0) throw new Exception();
    3. int sum = 0;
    4. for (int i = 0; i < a.length; i++) {
    5. sum += a[i];
    6. }
    7. return sum / a.length;
    8. }

  14. データの型を合わせよう
    1. int i1, i2, i3;
    2. long l1;
    3. ...
    4. i3 = (i1 > 10) ? i2 : (int) l1;
    この場合、可能であればキャストではなく、すべての型を long にした方がいい場合が多いです。
    1. long i1, i2, i3;
    2. long l1;
    3. ...
    4. i3 = (i1 > 10) ? i2 : (int) l1;

  15. ループのカウンターと終了値の型を合わせよう
    1. void func(long n) {
    2. for (long i = 0; i < n; i++) {
    3. ...
    4. }
    5. }

  16. else 句を書こう
    1. if (var1 == 0) {
    2. ...
    3. } else if (0 < var1) {
    4. ...
    5. } else {
    6. 例外処理 または コメント
    7. }

  17. default 句を書こう
    1. switch (var1) {
    2. case 0:
    3. ...
    4. break;
    5. case 1:
    6. ...
    7. break;
    8. default:
    9. 例外処理 または コメント
    10. break;
    11. }

  18. カウントするループの終了条件は比較しよう
    1. int[] a = ...;
    2. for (int i = 0; i < a.length; i++) {
    3. ...
    4. }

  19. 変数はひとつの目的で使おう
    1. for (int i = 0; i < MAX; i++) {
    2. data[i] = i;
    3. }
    4. if (min > max) {
    5. int work = max;
    6. max = min;
    7. min = work;
    8. }

  20. for 文の式には for 文の制御をさせよう
    1. for (int i =0; i < MAX; i++) {
    2. ...
    3. j++;
    4. }

  21. break 文はひとつ、continue 文は使わないようにしよう
    1. for (i = 0; ループの継続条件; i++) {
    2. ...
    3. if (終了条件1 || 終了条件2) {
    4. break;
    5. }
    6. if (!継続条件2) {
    7. ...
    8. }
    9. }

  22. switch 文で break 文を忘れないようにしよう
    1. switch (var1) {
    2. case 0:
    3. sig = ZERO;
    4. break;
    5. case 1:
    6. sig = PLUS;
    7. break;
    8. default:
    9. sig = MINUS;
    10. break;
    11. }
Top

inserted by FC2 system