メンバ変数 戻る
インスタンス変数

東京ではテレビはNHK、日テレ、テレ朝、TBS、フジ、テレ東といったテレビ番組が映ります。「映像を写す」メソッドを実行する毎に東京に設置しているという情報はパラメータとして渡されるでしょうか。きっとテレビはインスタンス化され、どこかのタイミングで「このテレビは東京に設置している」という情報を渡されたら、その情報を変更することなく保有しているでしょう。インスタンス化されても全ての情報が毎回毎回メソッドに渡されるわけではないのです。値をインスタンスは保有するのです。

テレビのインスタンスが生成され、これは「テレビ」のインスタンス毎に(偶然一致することはあると思いますが)異なる値です。このようにインスタンス毎に保有される値のことを、インスタンス変数と呼びます。

では保有する方法を見てみましょう。インスタンス生成後に「インスタンス名.インスタンス変数名 = 値」という方法で設定しています。

class テレビ { String 設置場所; 電波を受信 { } 映像を写す { } 音を鳴らす { } } class 設置場所を設定するためのクラス { public static void main(String[] args) { テレビ tv = new テレビ(); tv.設置場所 = "Tokyo"; } }
クラス変数

日本では2011年7月24日の停波されました。(正確には地域毎に異なりますが考慮しないことにします。)アナログ放送の電波を受信できる日付をインスタンス変数で保持することにしましょう。

さて、この日付ですがインスタンス毎に異なる値でしょうか。日本においては同じ日付が設定されるはずです。同じ値を保有するのにインスタンス生成毎に値を設定しないといけないのでしょうか。インスタンスの生成毎に値を設定していると、生成する回数に比例して処理時間がかかってしまいます。

このようにインスタンス毎ではなくクラス毎に同じ値を保有する変数のことをクラス変数と呼びます。

では保有する方法を見てみましょう。先ほどのインスタンス変数を設定する時とは異なり、インスタンスを生成していません。クラス変数の意味を考えれば当たり前ですね。インスタンス化する必要がないためインスタンス化前に直接クラスに値を設定しています。インスタンスを生成せずに「クラス名.クラス変数名 = 値」という方法で設定しています。

class テレビ { static String アナログ電波停波日; String 設置場所; 電波を受信 { } 映像を写す { } 音を鳴らす { } } class 停波日を設定するためのクラス { public static void main(String[] args) { テレビ.アナログ電波停波日 = "2011年7月24日"; } }
2つのインスタンスで確認する

実際に2つインスタンスを生成し、インスタンス変数とクラス変数の違いを確認しましょう。

  1. "AAAA"の設定前は何も値は設定されていませんので、a,bともにインスタンス変数とクラス変数ともにnull(設定されていない意)です。
  2. "AAAA"はクラス変数に値を設定しているので、a,bともにクラス変数に"AAAA"が設定され、インスタンス変数はともにnullです。
  3. "BBBB"はaのインスタンス変数に値を設定しているので、aのインスタンス変数は"BBBB"、他は変更されてません。
  4. "CCCC"はbのインスタンス変数に値を設定しているので、bのインスタンス変数は"CCCC"、他は変更されてません。
  5. "DDDD"はクラス変数に値を設定しているので、a,bともにクラス変数に"DDDD"が設定され、インスタンス変数はともに変更されていません。
class 違いを確認 { static String cls; String ins; public static void main(String[] args) { 違いを確認 a = new 違いを確認(); 違いを確認 b = new 違いを確認(); System.out.println("----------"); System.out.println("a.cls=" + a.cls + " a.ins=" + a.ins); System.out.println("b.cls=" + b.cls + " b.ins=" + b.ins); 違いを確認.cls = "AAAA"; System.out.println("----------"); System.out.println("a.cls=" + a.cls + " a.ins=" + a.ins); System.out.println("b.cls=" + b.cls + " b.ins=" + b.ins); a.ins = "BBBB"; System.out.println("----------"); System.out.println("a.cls=" + a.cls + " a.ins=" + a.ins); System.out.println("b.cls=" + b.cls + " b.ins=" + b.ins); b.ins = "CCCC"; System.out.println("----------"); System.out.println("a.cls=" + a.cls + " a.ins=" + a.ins); System.out.println("b.cls=" + b.cls + " b.ins=" + b.ins); 違いを確認.cls = "DDDD"; System.out.println("----------"); System.out.println("a.cls=" + a.cls + " a.ins=" + a.ins); System.out.println("b.cls=" + b.cls + " b.ins=" + b.ins); } }
インスタンス変数とクラス変数

実際に上記のサンプルを参照し、インスタンス変数とクラス変数の違いを確認できるプログラムを作成、動作確認を行いなさい。

インスタンスのクラス変数を変更

上記のサンプルの末尾に以下を追加して動作確認を行いなさい。その際、何が起こるか予想してから実施しなさい。

a.cls = "EEEE"; System.out.println("----------"); System.out.println("a.cls=" + a.cls + " a.ins=" + a.ins); System.out.println("b.cls=" + b.cls + " b.ins=" + b.ins);
クラスのインスタンス変数を変更

上記のサンプルの末尾に以下を追加して動作確認を行いなさい。その際、何が起こるか予想してから実施しなさい。

違いを確認.ins = "FFFF"; System.out.println("----------"); System.out.println("a.cls=" + a.cls + " a.ins=" + a.ins); System.out.println("b.cls=" + b.cls + " b.ins=" + b.ins);