3秒でわかる
クラスの中に宣言して、オブジェクトごとの状態を保持し続ける変数のこと。メソッドはこの値を読み書きしながら処理を進めます。
もう少し詳しく
どういうものか
フィールドは、クラスの内側に宣言する変数を指す。メソッドの中だけで生きるローカル変数と違って、そのオブジェクトが存在するあいだ値を保ち続ける。Java では「フィールド」、Python では「属性」、C++ では「メンバ変数」と呼ばれるが、指しているものはほぼ同じになる。オブジェクトの状態はフィールドが持ち、その状態を変える手続きをメソッドが持つ、という分担で書かれる。
なぜ必要か
同じ処理でも、対象ごとに違う値を覚えておかないと成り立たない。口座から出金する処理は、どの口座の残高なのかが分からなければ書けない。フィールドに残高を持たせておけば、メソッドの引数で毎回持ち回らなくても、そのオブジェクト自身の値として参照できる。データと手続きを一つにまとめる、という考え方の土台になっている。
具体例
public class BankAccount {
private String owner; // フィールド
private int balance; // フィールド
public BankAccount(String owner, int balance) {
this.owner = owner;
this.balance = balance;
}
public void withdraw(int amount) {
int fee = 100; // ローカル変数
this.balance -= amount + fee;
}
}fee はメソッドを抜けた時点で消えるが、balance はオブジェクトが残るかぎり保持される。
つまずきやすいところ
引数とフィールドを同じ名前にしたときに this を書き忘れると、代入がローカル変数へ向かってフィールドが初期値のまま残る。値が変わらないのにエラーも出ないので原因を探しづらい。もう一つは static を付けたときの挙動で、これはクラス全体で 1 つしか存在しない共有の値になる。オブジェクトごとに数えたいカウンタを static で宣言すると、全部の合計が入ってしまう。
似た用語との違い
| 用語 | 生存期間 | どこに属するか |
|---|---|---|
| フィールド | オブジェクトが残るあいだ | インスタンス |
| ローカル変数 | メソッドの実行中だけ | メソッド |
| static フィールド | プログラムの実行中ずっと | クラス |
覚え方
フィールドはオブジェクトの持ち物、ローカル変数はその場のメモにあたる。持ち物は次にそのオブジェクトを使うときも残っているが、メモは処理を抜けた瞬間に捨てられる。値を後から参照したいのか、その場かぎりなのかで置き場所を決める。