■大域変数と局所変数■

変数の有効範囲(スコープ)とは

変数には,有効範囲(スコープ)が存在する.これは,次のような人物名でも同じ話である.

山田家の太郎君 
田中家の太郎君

同じ太郎という名前なため,それぞれの家庭内では「太郎」君にお使いを頼むときには「太郎,買いものしてきて」と指示される.しかし,2人は別人であり,山田太郎君にお願いした仕事を,田中太郎君がしてくれるわけではない.

これは,Javaの変数でも同じである.

public class Example
{
	public static void main(String[] args)
	{
	int y = 100;
	int x = square(3); //関数squareの呼出
	}
				
	public static int square(int param)  //関数squareの本体
	{
		int y=param;
				
		y = y * y;
		return y;
	}
}

この例では次のふたつの変数がたまたま同じ名前である.

main関数の中のint y
funcA関数の中のint y

この2つの変数は,同じ名前であるがまったく別変数である.つまり,squareのyに値を代入しても,mainのyとは関係がなく,mainのyの内容が書き換わることはない.

これは,それぞれのyが宣言された関数の中だけで有効であることを意味し,そのことを有効範囲(スコープ)と呼ぶ.

有効範囲のルール

Javaにおける名前の有効範囲(スコープ)は,原則として次のルールに従う.

  • 中括弧{}で括られたブロック中で宣言された変数などは,そのブロック内だけで有効

つまり,次のように関数内だけでなく,if文の中だけで有効な名前も存在する.

public static int square(int param)  //関数squareの本体
{
	int y=param; //関数内で有効
				
	if(y>0)
	{
		y = y * y;
	}
	else
	{
		int z=-1;  //elseの中だけで有効な変数
		y=z;
	}
	System.out.println(z); //←範囲外なのでここでエラー
	return y;
}

その有効範囲のルールには,若干の例外がある.

  • 仮引数は,関数の中で宣言された変数と同様に扱われる
  • for文の()内で宣言された変数は,for文の繰り返し中だけで有効

2番めは次のようなもので,iとjは違う有効範囲を持った変数である.

for(int i=0; i<100; i++)
{
   int j;
}

有効範囲から出てしまった変数は消滅するため.変数jは,一度ループを繰り返すたびに消滅する.つまり一回前の繰り返しのときのjと,現在実行されている時のjは別の変数として扱われる.これに対し,iはfor文全体が終了するまでは消滅しない.次のwhile文でのiと同じ有効範囲を意味している.

{  //←while文全体を囲っているブロックが仮りに存在するとして考える
  int i;
  while(i)
  {
     int j;
  }
}

大域変数

有効範囲(スコープ)を持った変数のことを局所変数(ローカル変数)と呼ぶ.それに対して有効範囲のない,プログラム内のどこでも有効な変数のことを大域変数(グローバル変数)と呼ぶ.

しかし,Javaでは大域変数は存在しない.すべての変数は局所変数である.有効範囲が一番大きな変数は,メンバ変数である.メンバ変数についてはオブジェクトの所で説明するが,メンバ変数の一種にクラス変数がある.

int xyz; //大域変数はJavaでは存在しないので,ここで文法エラー
public class Example
{
	static int abc=100; //クラス変数
	public static void main(String[] args)
	{
		int y = 100;
		int x = square(abc); //関数squareの呼出
	}
					
	public static int square(int param)  //関数squareの本体
	{
		int y=param;
					
		y = y * y + abc;
		return y;
	}
}

一番上で宣言しようとしている変数xyzは,class宣言の外側にある.本来ならばここで宣言した変数は,すべての中括弧の外にあるので大域変数の意味を持つはずだが,Javaではこの位置で変数を宣言するとエラーにされる.

変数abcは,関数の外側かつclassの内側でstaticと宣言された変数である.これをクラス変数と呼ぶ.クラス変数の名前はクラスの内側全部で有効なため,関数mainと関数squareどちらでも読み書きすることができる変数となる.

クラス変数の利用

Javaでは,関数の返値はひとつしかreturnできない.複数の値を返したい場合には,クラス変数などのメンバ変数を介してそれに似た動作が書ける.例えば次のようにfuncを実行すると,クラス変数abcとdefに値を設定するようにしておけば,funcの2番めと3番めの返値のように使用することができる.

public class Example
{
	static int abc=0; //クラス変数
	static int def=0; //クラス変数
	public static void main(String[] args)
	{
		int x = func(300); //xに返値300
		int y = abc;       //yに3000=300*10
		int z = def;       //zに30=300/10
	}
					
	public static int func(int param)  //関数squareの本体
	{
		abc = param*10;
		def = param/10;
		return param;
	}
}