フィールド
フィールドはクラスの属性を定義します。
属性自体は変数の集まりです。
どの様なプログラムも結局のところデータと処理を記述したものです。
自由気ままにデータを処理していては、良いプログラにはなりません。そこで、「構造化プログラミング」で処理についたは、こうするべきだという手本が示されました。しかし、データについては型は規定しても、使われ方が多岐にわたるのでオブジェクト指向プログラミング以前の言語では規定はなく、プログラマ任せでした。
フィールドの書式はいくつかの変数宣言(同時に初期値を設定しても良い)をクラスの先頭で記述します。何もオブジェクト指向プログラミング以前の言語における変数宣言と変わりません。
Javaのデータに対する規定はどこにあるのでしょうか。それは、
フィールドのスコープ(有効範囲)と変数へのアクセス手法が明確
フィールド内の変数に対し、static修飾子を付けたスタティック変数と、修飾子を付けないインスタンス変数の使い分けが可能
ことです。これにより、使われ方が多岐にわたるデータを変数という形で扱うことが出来るようになっています。
フィールドのスコープ
勿論、フィールドが属すクラス内です。
クラス内のメソッドのローカル変数の名前とフィールド内の変数の名前が重複した場合には、ローカル変数が優先されます。そこで、フィールド内の変数をメソッド内でアクセスしたい場合は、その変数名の前にthis.を書き加えます。thisはJVMが用意してくれる変数(プログラマが宣言する必要がない)の1つで、インスタンス自身への参照が入っています。このため、「this. 変数名」と記述することで、ローカル変数ではなく、フィールド内の変数を明示する事になります。
また、メソッドが仮引数としてフィールド内の変数と同じ名前を持つ場合も同じです。仮引数名の前には何もつけず変数名だけを記述します。
なおスコープの違いから、スーパークラスとサブクラスのフィールド内に同じ名前の変数があっても名前の衝突は起きません。しかし、サブクラスからスーパークラスのフィールドにアクセスするときに名前の混乱が起きないようサブクラス内のフィールドへのアクセスにはthis.を付け、スーパークラス内のフィールドへのアクセスにはsuper.を付ければ、スコープを越えたアクセスも可能です。
static なフィールドヘのアクセス
Java では、プログラムの実行中に必要なクラスを読み込んで(ダイナミックリンクして)実行します。
クラスを読込むと、staticで修飾されたフィールド(内の変数)やメソッドは、「static領域」に配置されます。それ以外の部分は、「ヒープ領域」に配置されます。インスタンスが生成されるときには、ヒーフ領域にあるクラス定義に従ってインスタンスが生成されます。
このため、staticなフィールドはそのフィールドを持つクラスのインスタンスを作らなくても、既に存在していて使うことが出来ます。また、static なフィールドはインスタンス内には存在しないので、いくつか作られたインスタンスからstaticフィールドをアクセスすると、全てstatic領域内の同じフィールドをアクセスすることになります。
なお、static なフィールドにアクセスするには「クラス名.フィールド名」と記述するか、インスタンスを生成し「インスタンス変数名.フィールド名」(コンパイル時に「クラス名.フィールド名」に置き換えられる)でアクセスします。