新人SEの学習記録

14年度入社SEの学習記録用に始めたブログです。もう新人じゃないかも…

学習記録:定数のすべて

[Java]Javaの学習

内容: 7章 定数のすべて

1)置換定数
public static final double PI = 3.14;
public static final String MSG = "Hello!";
  • 置換されるタイミング
    • 基本型とString型はコンパイル時に、その他は実行時に置換される
    • よって、基本型・String型の定数を変更した場合、定数を使用している全てのクラスの再コンパイルが必要
  • 使用基準
    • 数値: 2度以上使われる場合、複数回使用され変更される可能性がある場合
    • String: 複数回使う場合、使用することで読みやすさを向上できる場合(文字列が非常に長くなる場合など)
  • ResourceBundleを使用した国際化などにも便利
2)ビットフィールド
public static final int POWER_WINDOW =1;
public static final int POWER_LOCKS = 2;
public static final int SNOW_TIRES = 4;
...
  • Cで良く使う、各ビットにある状態のON/OFFなどを割り当てる手法
  • JDKでは可視性の修飾子(public, protected, private)の状態に使っている
  • 速いし省メモリだが、拡張性が低く複数の属性を一つに結合してしまうのでオブジェクト指向に反する
  • Javaではあまり使わない方が良い
3)オプション定数
public class Country {
    public static final int JAPAN = 0;
    public static final int USA = 1;
    public static final int GERMANY = 2;
    ...
}

public class Address {
    private int country;

    public void setCountry(final int country) {
         this.country = country;
    }
}
  • ビットフィールドに似ているが、多くの場合連続した数値を使用
  • setCountry()で任意の値を渡せてしまう
    • MAX_VALUEとMIN_VALUEをCountryクラスで定義し、範囲チェックを行う必要
    • しかし、新しい国を追加した場合にMAX_VALUEを増やす必要
    • 100番台はアジア、200番台はヨーロッパ...などの区分けをするとMAX_VALUEの手法も使えない
    • Countryクラスを使用するユーザがチェックする必要がある=オブジェクト指向エンジニアリングに反する
  • 定数オブジェクトを使おう!
4)定数オブジェクト
public final class Country2 {
    public static final Country JAPAN = new Country2("JAPAN");
    public static final Country USA = new Country2("USA");
    public static final Country GERMANY = new Country2("GERMANY");

    private final String name;

    private Country2(final String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}

public class Address2 {
    private Country2 country;

    public void setCountry(final Country2 country) {
        this.country = country;
    }
}   
  • 各定数を任意の順番で宣言可能
    • 新しく国を付け加えるのも楽
    • 順番に並べる必要もない
  • 範囲の検証について
    • setCountryコードは引数にCountry2オブジェクトをとるため、Country2オブジェクト以外渡すことができない
    • Country2クラスではprivateコンストラクタが使われているため、ユーザが新規にCountry2クラスを生成できない
    • よって、範囲の検証を行う必要がない
  • 定数に関する便利な名前を付けることができる
  • 整数型を使用した定数オプションに比べ、性能上の悪影響はほとんどない

所感

  • 定数オブジェクトの作り方について良くわかった
    • 将棋プログラムを作ろうとしたときにかなり曖昧だったので
  • Cを使っていた身としてはビットフィールドが慣れているが、やっぱりわかりにくいよね