初期化と参照

目次
  • 解説
  • 1. 宣言時に代入できない場合
  • 2. 初期化とは
  • 3. なるべく初期化は使わない
問題に挑戦!
進捗を変更する




解説

1. 宣言時に代入できない場合


例えば、変数に条件によって異なる値を代入したいなど、宣言時には値が決定していないため代入できない場合があります。しかし、次のサンプルコードはエラーとなってしまいます。

    static void practiceInitialize() {
        String price; // 何も代入していない
        String ticket = "通常券"; // (ここは処理時の入力で変わる想定)
        if (ticket == "通常券") {
            price = "料金は1000円です。";
        }
        if (ticket == "特別券") {
            price = "料金は500円です。";
        }
        Logger.out(price); // 「初期化されていない」というエラーとなる
    }

ここで、10行目のように「変数の値を使う・変数の値を読み取る」ことを参照すると言います。変数は宣言してから参照するまでの間に、必ず型に応じた値を代入する必要があります。

もしもticketが「通常券・特別券」以外の場合には、5・8行目の代入している行が条件分岐(if文)によって実行されなくなるため、10行目でprice参照した時点で何も代入されていない状態となるということを、構文解析してあらかじめ警告してくれているのです。

なお、このように実行する前にわかるエラーをコンパイルエラー構文エラーと呼びます。

2. 初期化とは


ならばとりあえずその型にあった値=初期値を入れておこう、という対処を初期化と言います。

    static void practiceInitialize() {
        String price = ""; // 長さ0の文字列=空文字で初期化しておく
        String ticket = "通常券"; // (ここは処理時の入力で変わる想定)
        if (ticket == "通常券") {
            price = "料金は1000円です。";
        }
        if (ticket == "特別券") {
            price = "料金は500円です。";
        }
        Logger.out(price); // コンパイルエラーが消えた
    }

今学習している「メソッドの中に定義する変数=ローカル変数」以外の変数(クラス変数・インスタンス変数・配列の要素)では自動的に初期化が行われます。その場合に使われる初期値は型ごとに下表のようになっていますので、ローカル変数を初期化する際には同様にしましょう。

型の分類初期値
基本型booleanfalse
基本型byte(byte) 0
基本型short(short) 0
基本型int0
基本型long0L
基本型float0.0f
基本型double0.0d
基本型char'\u0000'
参照型クラス型null
参照型インターフェース型null
参照型配列型null(要素は型に応じた初期値)

なお、ローカル変数の場合には、String型にnullではなく長さ0の文字列=空文字を代入することも、一般的に初期化と呼ばれます。

3. なるべく初期化は使わない


前項のサンプルコードはエラーが解消され、ticketは「通常券・特別券」のいずれか、という暗黙のルールを守っていれば問題なさそうです。

しかし、時と共に暗黙のルールは忘れ去られます。「通常券」の名称を「当日券」に変更しただけで、「エラーなく動いているのにpriceが空っぽになる!」という問題が起きるのです。

このケースでは、次のサンプルコードのような構成を検討すべきです。

    static void practiceInitialize() {
        String price = "料金は1000円です。"; // 初期化ではなく通常時の値
        String ticket = "通常券"; // (ここは処理時の入力で変わる想定)
        if (ticket == "特別券") {
            price = "料金は500円です。";
        }
        Logger.out(price); // 特別な場合だけ値が書き換えられる
    }

その変数がいちばん取り得る値を宣言時に代入しておくことは、初期値という目的にそぐわない値の排除・条件分岐の削減・変更時の修正箇所削減などのメリットがあります。

初期値だったら(nullだったら)エラー、などの処理が必要な場合以外では、変数の宣言時にあらかじめ代入しておける値を見つけましょう。

問題

確認問題


確認問題1

この中で初期化の説明として正しいものはどれか?