static
という形容詞がいつも main()
に付いていますね。たとえば
class Hello { public static void main(String[] args) { System.out.println("こんにちは"); } }
という具合です。
この static
について,ちょっと実験してみましょう。次のようなプログラムを作ります。
class Test { static int value; static void setValue(int x) { value = x; } public static void main(String[] args) { setValue(5); System.out.println("値は " + value + " です"); } }
これを実行すると「値は 5 です」と画面に現れます。
この static
という語を外してみましょう(main()
の頭の static
は残しておきます)。
class Test { int value; void setValue(int x) { value = x; } public static void main(String[] args) { setValue(5); System.out.println("値は " + value + " です"); } }
これで javac Test.java
としてみると,次のようなエラーメッセージが出て,コンパイルできません。
Test.java:7: static でない メソッド setValue(int) を static コンテキストから参照することはできません。 setValue(5); ^ Test.java:8: static でない 変数 value を static コンテキストから参照することはできません。 System.out.println("値は " + value + " です"); ^ エラー 2 個
これは要するに
static
なメソッドからstatic
でないものを使えないよ
という意味のエラーメッセージです。
static
なものは,コンパイルした時点で作成されます。ところが,static
でないものは,コンパイルした時点ではまだ存在しません。実行時に,new
という命令を使って,自分で作らなければならないのです。
上のプログラムを正しくすると,次のようになります。
class Test { int value; void setValue(int x) { value = x; } public static void main(String[] args) { Test t = new Test(); // Test のインスタンス t を作る t.setValue(5); System.out.println("値は " + t.value + " です"); } }
new
でできたものを,そのクラスのインスタンスといいます。インスタンスの作り方の決まり文句は,
クラスの名前 インスタンスの名前 = new クラスの名前();
です。上の例では
Test t = new Test();
となっていますね。Test
がクラスの名前,t
がインスタンスの名前です。
一つのクラスから複数のインスタンスを作ってもかまいません。たとえば
class Test { int value; void setValue(int x) { value = x; } public static void main(String[] args) { Test t = new Test(); // Test のインスタンス t を作る Test u = new Test(); // Test のインスタンス u を作る t.setValue(5); // t の value を 5 にする u.setValue(7); // u の value を 7 にする System.out.println("値は " + t.value + " です"); System.out.println("値は " + u.value + " です"); } }
とすれば,
値は 5 です
値は 7 です
と出力されます。
このように,クラスの static
でない部分は,一種の型紙のようなもので,それだけでは使えませんが,それからいくつでもインスタンスを作り出すことができます。
このように考えれば,main
が static
でなければならないのも当然ですね。main
が最初から存在しなければ何もできないからです。
配列とは,変数の並びです。たとえば100個の変数が必要なとき,
int a, b, c, d, e, ...;
のようにいちいち作っていては日が暮れてしまいます。これを
int[] a = new int[100];
のようにすれば,
a[0]
,a[1]
,a[2]
,……,a[99]
という100個の変数ができます。
この
int[] a = new int[100];
は
int[] a; a = new int[100];
のように分けて書いてもかまいません。
a
という配列の長さは,a.length
として得られます。上の例では a.length
は100です。
次の例を見てください。
class Test { public static void main(String[] args) { long[] value = new long[92]; value[0] = value[1] = 1; for (int i = 2; i < value.length; i++) { value[i] = value[i-1] + value[i-2]; System.out.println("value[" + i + "] = " + value[i]); } } }
3行目で value[0]
から value[91]
までの92個の long
型の変数を作っています。
Javaでは,クラスのインスタンスと同様に,配列も new
という命令で作りますが,これはクラスのインスタンスとは違うものです。
上のプログラムを次のようにするとエラーになります。
class Test { long[] value; // ここに持っていくとエラーになる public static void main(String[] args) { value = new long[92]; value[0] = value[1] = 1; for (int i = 2; i < value.length; i++) { value[i] = value[i-1] + value[i-2]; System.out.println("value[" + i + "] = " + value[i]); } } }
static
なメソッドから static
でないものは使えないからです。対処法は,上の2行目を
static long[] value;
とするか,あるいはインスタンスを作って
class Test { long[] value; public static void main(String[] args) { Test t = new Test(); t.value = new long[92]; t.value[0] = t.value[1] = 1; for (int i = 2; i < t.value.length; i++) { t.value[i] = t.value[i-1] + t.value[i-2]; System.out.println("value[" + i + "] = " + t.value[i]); } } }
とすればいいのでしたね。配列を作るのにも new
を使うので混乱しやすいと思いますが,クラスのインスタンスを作るのを忘れないでください。
なお,次のような書き方もできます。
class Test { static long[] value = new long[92]; public static void main(String[] args) { value[0] = value[1] = 1; for (int i = 2; i < value.length; i++) { value[i] = value[i-1] + value[i-2]; System.out.println("value[" + i + "] = " + value[i]); } } }
次の書き方も大丈夫です。
class Test { long[] value = new long[92]; public static void main(String[] args) { Test t = new Test(); t.value[0] = t.value[1] = 1; for (int i = 2; i < t.value.length; i++) { t.value[i] = t.value[i-1] + t.value[i-2]; System.out.println("value[" + i + "] = " + t.value[i]); } } }
static
にしない場合,インスタンス名.変数名
のような書き方が面倒なら,次のように static
でないメソッドに実際の作業をさせてしまうと楽です。
class Test { long[] value = new long[92]; void doit() { value[0] = value[1] = 1; for (int i = 2; i < value.length; i++) { value[i] = value[i-1] + value[i-2]; System.out.println("value[" + i + "] = " + value[i]); } } public static void main(String[] args) { Test t = new Test(); t.doit(); } }
つまり,static
でないメソッドからなら,インスタンス名を付けないで変数やメソッドが使えます。これは,同じインスタンスの中だけの話です。
なお,この main()
の中はさらに
new Test().doit();
のように2行を1行に縮めて書くことができます。
Last modified: 2005-12-25 12:29:04