インスタンス化無しで使える
クラス内の変数やメソッドに「static」を付けるとインスタンス化しなくても利用できるようになります。プログラム例と実行結果を掲載します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
package jp.ayax.object; public class Main { public static void main(String[] args) { System.out.println(Test10.getNum2()); Test10.step2(); Test10 t1 = new Test10("t1"); t1.step1(3,4); Test10 t2 = new Test10("t2"); t2.step1(5,6); t2.print(); t1.print(); } } class Test10 { int num1; static int num2=9; String name; public int getNum1(){return(num1);} static public int getNum2(){return(num2);} public Test10(String name){ this.name = name; } public void step1(int num1,int num2){ System.out.println("【"+name+"】step1:"+num1+"⇒"+"num1"+":"+num2+"⇒num2"); this.num1 = num1; this.num2 = num2; } static public void step2(){ System.out.println("public step2"); } public void print(){ System.out.println("【"+name+"】print:num1="+num1+":num2="+num2); } } |
1 2 3 4 5 6 |
9 public step2 【t1】step1:3⇒num1:4⇒num2 【t2】step1:5⇒num1:6⇒num2 【t2】print:num1=5:num2=6 【t1】print:num1=3:num2=6 |
クラスTest10の21行目、25行目、34行目で「static」の記述があります。
21 |
static int num2=9; |
25 |
static public int getNum2(){return(num2);} |
34 |
static public void step2(){ |
これでインスタンス化せずに、6行目、7行目のように利用することができます。
6 7 |
System.out.println(Test10.getNum2()); Test10.step2(); |
「じゃー全部staticつければいいのでは?」はい。そう感じますよね。でもちょっと問題があります。
staticの落とし穴
このプログラムは、9行目~15行目でクラスTest10のインスタンスを作成しt1,t2の変数に格納しています。そしてstep1メソッドを呼び出すことにより、クラス内変数num1、num2に値を格納し、メソッドprintで表示しています。
9 10 11 12 13 14 15 |
Test10 t1 = new Test10("T1"); t1.step1(3,4); Test10 t2 = new Test10("T2"); t2.step1(5,6); t2.print(); t1.print(); |
実行結果を見ると不思議なことがあります。インスタンスt1のnum2の値が6になっているのです。10行目でnum2に4を設定し、15行目で表示していますが6と表示されています。
3 4 5 6 |
【t1】step1:3⇒num1:4⇒num2 【t2】step1:5⇒num1:6⇒num2 【t2】print:num1=5:num2=6 【t1】print:num1=3:num2=6 |
この6はt2のnum2と同じ値です。前回、インスタンス毎にメモリが展開されるので格納される値もそれぞれ別になるとの説明がありました。今回はt1,t2の変数num2が同じ値になっているようです。
この原因は変数num2がstaticで定義されているからです。staticで定義するとインスタンス化せずに使えますが、インスタンス化してもインスタンス毎にメモリに展開されません。したがって、インスタンスt1、t2の変数num2は同じ1つのnum2を参照しているのです。
メモリの展開イメージで考えると、プログラムが実行された時点でstaticのモノも展開されます。
クラスがインスタンス化されるとメモリに展開されますが、staticなモノは1つのモノを参照するだけです。
stticを付けることによりインスタンス化せずとも使えますがインスタンス毎に利用できなくなります。そのためstaticの利用は限定的になります。さらに探求する必要がありそうですが、この連載ではここまでとしますね。