アルゴリズムとプログラミング (Algorithms and Programming) 第10回:インスタンス変数、クラス変数 •インスタンス変数とクラス変数 •インスタンスメソッドとクラスメソッド •ローカル変数とスコープ •変数の寿命、ガーベージコレクション 講義資料等: http://www.pe.titech.ac.jp/~watanabe/lecture/ap/index-j.html インスタンス変数 class Point { // 点クラス double x; // x座標 double y; // y座標 } Point p1 = new Point(); Point p2 = new Point(); p1とp2はクラスは同じだが、 別のインスタンスであり、それ ぞれ個別に変数double x, double yを持つ これまで出てきた変数は、 インスタンスごとにメモリ領 域が個別に割り当てられ、 別々に読み書きができた インスタンス変数 Point: p1 Point: p2 x: 1.5 y: 2.0 x: 0.2 y: 0.0 お互い無関係に 読み書き可能 クラス変数 同じクラスのどのインスタンスからでも、共 通の1つの変数(=メモリ領域)を読み書き したい場合がある p1からクラス変数の値を 変更すると、p2から見ても 値が変更されている!! クラス変数 実体は1つ Point: p1 Point: p2 x: 1.5 y: 2.0 count : x: 0.2 y: 0.0 count : count : 2.0 クラス変数 クラス全体で 共有する変数 クラス変数の宣言 class Point { // 点クラス double x; // x座標 double y; // y座標 public static int count; } static修飾子 クラス変数へのアクセス方法: オブジェクト変数名.クラス変数名 クラス名.クラス変数名 クラス変数の宣言と利用の例 class Point { // 点クラス double x; // x座標 double y; // y座標 //クラス変数の定義と初期化(static修飾子の有無で出力結果を比較せよ) public static int count = 0; Point( double a, double b ){ コンストラクタ x = a; y = b; count++; } } class SampleAP0801 { public static void main(String[] args){ // インスタンスが生成される前からクラス変数は存在する! System.out.println("count=" + Point.count); count=0 Point p1 = new Point(1.0,2.0); System.out.println("count=" + p1.count); Point p2 = new Point(3.0,4.0); count=1 System.out.println("count=" + p2.count); count=2 } } クラスメソッド クラス単位で共有されるメソッド インスタンス変数にアクセス不可 インスタンスメソッドの呼び出し不可 クラスメソッドは、クラス内で定義されてい るのでクラスのメンバーといえるが、実体 はインスタンスの外に存在する オブジェクト(実体) インスタンス1 インスタンス変数 インスタンスメソッド クラス変数 クラスメソッド クラス定義 インスタンス2 static static インスタンス3 クラスで共有 static static アクセス class Point { // 点クラス double x; // x座標 インスタンス変数 double y; // y座標 //クラス変数、クラスメソッドの定義 クラス変数 public static int count = 0; クラスメソッド public static void printValue(){ System.out.println( "value:" + count ); } クラスメソッド public static void printValue(int i){ System.out.println( "value:" + i ); } クラスメソッドの中からインスタンス変数で } あるx,yを参照することはできない! class SampleAP0802 { public static void main(String[] args){ // インスタンスが生成される前からクラス変数、クラスメソッドは存在する! Point.count = 5 ; value:5 Point.printValue(); Point.printValue(6); value:6 Point o = new Point(); o.printValue(7); value:7 } } main()はクラスメソッドだった! class ユーザ定義 { public static void main(String[] args){ 処理; } } main()メソッドが実行される約束 になっている どこで宣言された変数か? 変数の3つの分類 宣言される場所 •インスタンス変数 •クラス変数 •ローカル変数 クラス内 メソッド内 ローカル変数が見える 範囲(スコープ)と寿命 中カッコ{}で囲まれたブロックがスコープの目印 class SampleAP0803 { public static void main(String[] args){ int x = 0; for( int i = 1; i <= 10; i++) { x = x + i; } System.out.println("total = " + x ); } } 変数iの値をこのforブロックの外から参照することはできない 変数xの値はforブロック内からでも参照可能 変数の寿命 使い終わった変数は破棄され、使用 していたメモリが解放される (ガベージコレクション) ローカル変数の寿命:ブロックの最初にメモリが確保さ れ、ブロックの終わりで破棄される インスタンス変数の寿命:newで生成されてから、 最後に参照された後、Java VM が判断したタイミ ング クラス変数の寿命:プログラムの開始から終了まで バッティングしても有効 ローカル変数 SampleAP0804.java class X { static int i = 100; クラス変数 int j = 200; インスタンス変数 void printValue(){ System.out.println("i= System.out.println("j= int i = 123; ローカル変数 int j = 456; System.out.println("i= System.out.println("j= } } " + i ); " + j ); " + i ); " + j ); SampleAP0804.java続き class SampleAP0804 { public static void main(String[] args){ X o = new X(); o.printValue(); } } 実行結果 i= j= i= j= 100 200 123 456 ローカル変数 クラス変数・インスタンス変数 変数名がバッティングした場合は ローカル変数が優先される バッティングしないように名前を付けるのが望ましい 値を変更しない変数(定数)の宣言 final修飾子 class X { static final int MAX = 100; final static int MIN = -100; final int DEFAULT = 10; 値を変更しないのなら、インスタンスご とにこの定数のためにメモリを確保す } るのは無駄といえる→普通はクラス変 数にする(static) class SampleAP0805 { public static void main(String[] args){ System.out.println("value= " + X.MAX); System.out.println("value= " + X.MIN); X o = new X(); System.out.println( "value= " + o.DEFAULT); } } まとめ •インスタンス変数とクラス変数 •インスタンスメソッドとクラスメソッド •ローカル変数とスコープ •変数の寿命、ガーベージコレクション •final修飾子
© Copyright 2024 ExpyDoc