TOP設計・移行・活用> リテラルは使用しない(C_VAL002)
Javaコーディング規約
Javaコーディング規約

第7回:変数に関するコーディング規約
著者: 電通国際情報サービス
高安 厚思、東田 健宏、藤村 浩士   2005/11/4
前のページ  1  2   3  4  次のページ
リテラルは使用しない(C_VAL002)

   リテラルとはコード上に直接書かれた数値や文字列のことをいいます。コードの中にリテラルがあっても、その値単体ではどのような意味を持つ値なのかがわかりにくくなります。また、同じ用途のリテラルが複数箇所で使われているようなケースでは、そのリテラルの値が変更になった時に複数の該当箇所を漏れなく確実に修正しなければならなくなります。

   以下のサンプルのgetSubCategory()メソッドは、図1のコード体系を持つ製品コードの中からサブカテゴリをあらわす3桁を抽出するメソッドですが、コードを見るだけではリテラルとして使われている3や6の値が何を意味しているのか読み手にすぐには伝わりません。加えて、将来製品カテゴリの桁が4桁に増えた場合、複数の箇所を修正しなければならず保守性もよくありません。

悪い例
public class Product {
     ⁄** 製品コード *⁄
     private String productCode;

     ⁄⁄…

     public String getSubCategory(){
          return productCode.substring(3, 6);
     }
}
3桁を抽出するメソッド
図1:3桁を抽出するメソッド

   以下のようにすることで、読み手にコードの意図が明確に伝わるとともに、将来製品カテゴリの桁が4桁に増えたとしても、CATEGORY_LENGTHの値を3から4に修正するだけで済みます。

良い例
public class Product {
     ⁄** (製品コードに含まれる)カテゴリコードの長さ *⁄
     private static final int CATEGORY_LENGTH = 3;

     ⁄** (製品コードに含まれる)サブカテゴリコードの長さ *⁄
     private static final int SUB_CATEGORY_LENGTH = 3;

     ⁄** 製品コード *⁄
     private String productCode;

     ⁄⁄…

     public String getSubCategory(){
          return productCode.substring(CATEGORY_LENGTH, CATEGORY_LENGTH + SUB_CATEGORY_LENGTH);
     }
}
   ただしこの規約では、forのカウンタ変数の初期化で0などのリテラルを用いる場合などは例外として認めています。


配列宣言は「型名[]」にする(C_VAL003)

   配列の宣言形式は「型名[] 変数名」が一般的ですが、Javaでは「型名 変数名[]」もC言語の名残として記述できるようになっています。

   しかし以下のように「型名[] 変数名」の方が、「int配列型のsampleArrayという変数を宣言し、その変数に対して要素が10個まで格納できるインスタンスを生成して代入した」ということを自然に読み取ることができますので、配列の宣言形式は「型名[] 変数名」に統一してください。

public class FixedSample{
     private int[] sampleArray = new int[10];
}
できるだけローカル変数を利用する(C_VAL004)

   クラス変数やインスタンス変数へのアクセスは、ローカル変数へのアクセスに比べて時間がかかってしまいます。変数に頻繁にアクセスする時は、アクセス速度が速いローカル変数を用いることで実行速度が改善します。

ローカル変数を利用した例
public class FixedSample {
     private int result;

     public void addNumber(int[] numbers) {
          ⁄⁄一時的なローカル変数に代入
          int tempSum = result;
          for (int i = 0; i < numbers.length; i++) {
               tempSum += numbers[i];
          }
     result = tempSum;
     }
}
   ただしこの規約は可読性を低下させることにもなります。この規約の適用は実行速度についてプロファイリングを行ったうえで、どうしてもパフォーマンスの改善が必要な時のみとしたほうがよいでしょう。


定数はfinalで宣言する(C_VAL005)

   プログラムが動作している間、ずっと値が変わらないものは定数です。このようなものに対しては、final宣言をすることによって、読み手に定数であることを明示してください。

   また、final宣言が付加された定数に対して誤って値を代入しようとすると、コンパイルエラーが発生し、プログラムミスを防ぐことができます。


ローカル変数とインスタンス変数を使い分ける(C_VAL006)

   ローカル変数は、メソッドの中だけでしか使わない値を保持したい時に使用します。

   ローカル変数は、その変数が宣言されているメソッドが呼び出された時に生成され、呼び出し元に処理が戻るときに破棄されます。したがって、別のメソッドがこの変数にアクセスできないのはもちろんですが、もし複数のスレッドが同じメソッドを呼び出したとしても、別々のローカル変数が生成されるため競合による不整合は発生しません。

   一方でインスタンス変数は、インスタンスの状態を保持したいときに使用します。

   インスタンス変数は複数のメソッドで共有されるので、各々のメソッドで正しく値を変更しているか予定外のメソッドから誤って値を変更していないかについて、プログラマが常に気を配っておく必要があります。もし複数のスレッドが同時にメソッドを呼び出すことがある場合は、インスタンス変数の競合によって値の不整合が発生しないようにスレッドの同期を制御してやらなければなりません。

   このようにローカル変数とインスタンス変数を比べると、インスタンス変数の扱いの方が難しいです。したがってメソッドの中だけでしか使わない値を保持したい時は、ローカル変数を使うようにしてください。

前のページ  1  2   3  4  次のページ


株式会社電通国際情報サービス 開発技術センター 高安 厚思
著者プロフィール
株式会社電通国際情報サービス  高安 厚思
株式会社電通国際情報サービス 開発技術センター
Java(J2EE)/オブジェクト指向の研究開発やプロジェクト支援、開発コンサルティングに従事。モデル、アーキテクチャ、プロセスが探求対象。今回は Javaコーディング規約2004の仕掛け人。


株式会社電通国際情報サービス 開発技術センター 東田 健宏
著者プロフィール
株式会社電通国際情報サービス  東田 健宏
株式会社電通国際情報サービス 開発技術センター
CTI、Webアプリの開発経験を経て、現在は主にプロジェクトマネジメント支援、プロセスエンジニアリング、ソフトウェア工学研究開発に従事。最近はコーチング、ファシリテーションといったヒューマン系スキルに興味を持ち日々修得に努めている。


株式会社電通国際情報サービス 藤村浩士
著者プロフィール
株式会社電通国際情報サービス  藤村 浩士
株式会社電通国際情報サービス アウトソーシング事業部所属
Java(J2EE)に関わる研究開発やプロジェクト支援の経験を経て、現在は、大手企業の業務会計システムの開発プロジェクトに従事。開発の傍らで、プロジェクトの「見える化」にも関心があり、オープンソースを組み合わせて「見える化」の実現に勤しんでいる。


INDEX
第7回:変数に関するコーディング規約
  はじめに
リテラルは使用しない(C_VAL002)
  インスタンス変数
  クラス変数