アルゴリズムとプログラミング

アルゴリズムとプログラミング
(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修飾子