読者です 読者をやめる 読者になる 読者になる

けつあご日記

こんちは.菊地です.なんか浅ーいことをいろいろ書きます

【Java】変数の初期化の挙動はローカル/フィールドで異なる

Java

Oracle Bronzeの勉強中のメモ.
以下問題.Java SE7 Bronze問題集(インプレスジャパン)より.

次のプログラムをコンパイル,実行したときの結果として,正しいものを選びなさい(1つ選択).

public class SuperClass {
    private int num;
    public void setNum(int num) {
        this.num = num;
    } 
}
public class SubClass extends SuperClass {
    private int num;
    public int getNum() {
        return this.num;
    }
}
public class Main {
    public static void main(String[] args) {
        SubClass sub = new SubClass();
        sub.setNum(10);
        System.out.println(sub.getNum());
    }
}

選択肢
A. SubClassの2行目でコンパイルエラーが発生する
B. Mainクラスの4行目の実行中に例外がスローされる
C. 0が表示される
D. 10が表示される

SubClassのnumは初期化されていないので解答はCということだったのだが,自分の記憶は「初期化していない変数を使うとコンパイルエラーになり,配列を宣言したときは例外的に中身の変数はデフォルトの初期化がなされる」というものだった.つまり,Mainの5行目でコンパイルエラーだと思った.

試しに色々いじってみると,ローカル変数かフィールド変数かで挙動が異なるようだ.

public class Test {
    static int val1;
    static boolean val2;
    float val3;
  
    public static void main(String[] args) {
        System.out.println(val1);
        System.out.println(val2);

        Test t = new Test();
        System.out.println(t.val3);

        //int x;
        //System.out.println(x); 
  }    
}

/*
実行結果
0
false
0.0


コメントアウトを外すとコンパイルエラー

変数xは初期化されていない可能性があります
    System.out.println(x);
                       ^
*/

フィールド変数ならインスタンス/staticにかかわらず自動で初期化され,ローカル変数は明示的に初期化せず使うとコンパイルエラーになるってことでよさそう.調べたら詳しいサイトがあった.finalにした場合についても書かれていて参考になる.

d.hatena.ne.jp

にしてもなぜわざわざこんな設計にしているんだろう?teratailに投げてみたので,回答があったら追記します.

※teratailに回答がついたので追記.とりあえずは納得できたかな...
teratail.com



↓アフィカスリンク

スッキリわかるJava入門 第2版 (スッキリシリーズ)

スッキリわかるJava入門 第2版 (スッキリシリーズ)

徹底攻略 Java SE 7/8 Bronze 問題集[1Z0-814]対応

徹底攻略 Java SE 7/8 Bronze 問題集[1Z0-814]対応

  • 作者: 志賀澄人,山岡敏夫,株式会社ソキウス・ジャパン
  • 出版社/メーカー: インプレス
  • 発売日: 2015/06/12
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る