2015年11月1日日曜日

Static変数・Staticメソッドとはなにか

Staticというのは「静的だよ」という意味で動的な変更のきかない変数やメソッドです。すべての同一のStatic変数が共通の値をもったりStaticメソッドが共通の処理をしたりします。「オブジェクト特有の変数じゃないよ、クラス固有の変数だよ」という意味でもあります。といってもよくわかりませんね。なので実際にコードを書いて確かめてみます。


class Static_dayo{
static int a;
int b;
}

public class Test {
public static void main(String args[]) {
System.out.println("Hello World!");

Static_dayo staticdayo = new Static_dayo();
staticdayo.a = 1;
staticdayo.b = 2;
Static_dayo staticda = new Static_dayo();
staticda.a = 3;
staticda.b = 4;


System.out.println(staticdayo.a);
System.out.println(staticdayo.b);
System.out.println(staticda.a);
System.out.println(staticda.b);
}
}
実行結果。1234にならない。

Static_dayoクラスのオブジェクト「staticdayo」および「staticda」の2つをTestクラス内部で作りました。これらを利用してメンバ変数にアクセスして
値を代入しています。でも、それぞれ1234を代入したのに結果は3234になっています。

これはなぜかというと「Static_dayoクラスのメンバ変数aがStaticだから」です。bはStaticではないのでキチンと値の変更が反映されます。

Staticは英語で「静的な」という意味です。メンバ変数をStaticにするとその値は静的な変数になり、動的に変更することができなくなります。すなわち「Static変数の値を一度変更するとすべての(同一の名を持つ)Static変数がその値に変更される」のです。よって、上記の例ではメンバ変数xは最後に値「3」が代入されているため、すべてのメンバ変数xが3として扱われます。だから結果が1234じゃなくて3234になったのでした。

じゃあなぜ静的になったのかというと、static変数はクラス固有の変数だからです。static変数はクラス固有の変数であり、いくらオブジェクトをつくろうが、すべてのオブジェクトでstatic変数の値は共通のものとして扱われるのであり、これはこのstatic変数がクラス固有の値だからです。

逆に、staticではない変数はオブジェクトを作るたびに(オブジェクトごとに)その値を変更することができます。これはstaticではない変数はオブジェクト固有の変数であり、その値はオブジェクト毎に変わるからです。

このオブジェクト固有の変数を動的なものであるとすれば、クラス固有の変数であるstatic変数は静的であると考えることができます(いくらオブジェクトを作ってもstatic変数は値を変えないからです)。

こういう意味で動的ではない、静的なわけですね。そのためstatic変数はオブジェクトを作らなくてもよびだすことが可能です。

TestClass.variable1 = 1;
こんな感じで変数呼び出しができる
非staticの場合はできない

なお、staticは変数だけではなくメソッドにもつけることができます。メソッドに「static」をつけると、このメソッドは静的なメソッドとなります。このstaticメソッドはstatic変数と同様に呼び出す際にオブジェクトを作らなくても直接呼び出すことができます。

class Static_dayo{
static int getx(int x){
return x*2 ;
}
}

public class Test {
public static void main(String args[]) {
int aaa = Static_dayo.getx(3);
System.out.println(aaa);
int bbb = Static_dayo.getx(9);
 System.out.println(bbb);
}
}

こんな感じで直接アクセスできる。
実行結果。
Static変数と違ってStaticメソッドでは(操作する変数がstaticでないため)値が共通になるわけではない。

static変数・staticメソッドからはstatic修飾子がついていない変数/メソッドは呼び出せません。
しかし、staticなもの同士ならお互いが固有なものとして扱われてるからお互いに呼び出し合うことができます。

staticの用途としては次のものが考えられます。

1. 全てのクラスで使用できる定数を用意したい。
staticな定数を宣言したクラスを作る。staticな変数には共通のコードでアクセスできる。

2. 全てのクラスから利用できる共通処理を作る。
staticなメソッドを実装したクラスを作る。staticなメソッドには共通のコードでアクセスできる。

3.staticは一つしか存在できない。
一つしか存在できない特性を活かした処理を作ることができる。

参考文献
技術の犬小屋「static(静的変数/静的メソッド)についての復習」2015年11月1日閲覧。
Javaちょこっとリファレンス「staticメソッド/static変数」2015年11月1日閲覧。