フィールドとローカル変数を理解する
フィールドはクラスやインスタンスの状態を保持し、ローカル変数はメソッド等の処理の中で使います。宣言位置、初期値、スコープ、同名変数が現れた場合の名前解決を分けて学びます。
この単元で学ぶこと
- フィールドとローカル変数の宣言位置を区別する
- 既定値と確定代入を判断する
- 同名変数による隠蔽とthisを追う
本文解説
宣言する場所 class Box { int n; void run(){int x=1;} }ではnがフィールド、xがローカル変数です。nは実体の状態として他のインスタンスメソッドからも扱えます。xはrunのブロック内で名前を使える処理用の変数です。
フィールドの既定値 intフィールドは0、booleanはfalse、参照型はnullから始まります。new Box()直後でも未初期化というコンパイルエラーなしに読めます。ただしnull参照フィールドのインスタンスメソッドを呼べるという意味ではありません。
ローカル変数の確定代入 void run(){int x;System.out.print(x);}は不正です。フィールドnを0で読めることとは別規則です。ローカル変数は使用前に値を明示代入するか、全到達経路で代入済みとコンパイラが証明できる必要があります。
明示的なフィールド初期化 int n=4;と宣言すればnew時に4を設定します。二つのBoxはそれぞれその初期値から始まります。nをメソッドで更新した実体と、新しく作った実体のnは独立です。
ローカル変数による隠蔽 int n=2を持つクラスでvoid run(){int n=5;System.out.print(n);}は5です。メソッド内の同名宣言がフィールドを隠します。System.out.print(this.n)なら実体の2です。thisは現在の受け手を表し、staticの文脈では使えません。
仮引数も近い名前 void set(int n){n=n;}は仮引数を自分自身へ代入するだけでフィールドを変えません。this.n=nなら左がフィールド、右が仮引数です。よく使う名前の一致は合法ですが、どちらを更新するか明示する必要があります。
呼出し間の状態 void next(){int local=0;local++;n++;}を二回呼ぶとlocalは毎回1ですがnは0→1→2と残ります。ローカルの初期化文は呼出しごとに評価されます。フィールドは同じ実体を使う限り前回の更新を保持します。
アクセスを制限する private int n;は別トップレベルクラスから直接アクセスできません。同じクラス内のpublic int get(){return n;}等を通じて値を返せます。状態を直接公開せず、更新メソッドで妥当性を確認するカプセル化の基礎になります。
図解
重要ポイント
- フィールドはクラス本体、ローカル変数はメソッド等のブロックで宣言する。
- フィールドには型に応じた既定値がある。
- ローカル変数には読取り前の確定代入が必要。
- 同名のローカル変数があれば単純名はそちらを表す。
間違えやすい点
- フィールドの既定値をローカル変数へ適用しない。
- 同じ名前なら常に同じ格納場所と思わない。
- privateフィールドを別トップレベルクラスから直接読まない。
用語解説
- フィールド
- クラス本体で宣言する状態用の変数。
- ローカル変数
- メソッド等のブロック内で宣言する変数。
- 隠蔽
- 同名の近いスコープの宣言により単純名の参照先が変わること。
関連教材
参考資料
教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。
確認問題の出題・採点や学習履歴の保存にはログインが必要です。