Javaのstaticはどういう意味? #プログラム初心者からの脱出①

Java の static 宣言の意味?

知人から、Java の static 宣言の意味を質問されました。例えば次の場合、どうちがってくるのでしょう。

public class Car {
    // 色
    private String color;
    // 形
    private static String shape;
}

「色」は通常のフィールドです。「形」は static 宣言されたフィールドです。


最初に簡単に説明をしてしまうと…

JVMの実行時に以下のようになります。

・通常のフィールドは、インスタンス(車)に生成されます。

・static 宣言したフィールドは、クラス(車の設計書)に生成されます。


実際にソースコードで見てみましょう。

Car carA = new Car();
Car carB = new Car();

carA.color = “赤”;
carA.shape = “四角”; //・・・①

carB.color = “緑”;
carB.shape = “丸”; //・・・②

// -----
// 出力結果(System.out.println)
// carA: 赤, 丸
// carB: 緑, 丸

color(色) は 通常のフィールド、shape(形) は static のフィールドでした。

shape(形) はメモリ上、クラスに生成されますので①と②は実際は同じフィールドを参照しています。したがって、shape(形) は carA も carB も「丸」になります。

static 宣言されたフィールドはクラスに紐づくフィールドなので、次のように書くべきです。

Car carA = new Car();
Car carB = new Car();

carA.color = “赤”;
Car.shape = “四角”; //・・・①

carB.color = “緑”;
Car.shape = “丸”; //・・・②

①と②で同じフィールドを参照していることがよくわかると思います。


補足で少し小難しい説明を付け加えると…

final 修飾子を宣言しない static フィールドはグローバル変数(アプリケーション内で1つだけの共有変数)と同様に扱われますので、使用を避けるべきです。

先ほど、車の形に「四角」と「丸」の値を入れました。今は短いソースコードなので値がどこで変更されたのかがわかります。

しかし、実際のソースコードはもっと長いですし、クラスも多く作られます。このとき、どこでフィールドの値が変更されたのか読み解くのは非常に困難です。

以下のことを心がけるとよいと思います。

・フィールドを static 宣言しないこと

・フィールドを static 宣言する場合は、static final とすること


メソッドや内部クラスにも static は宣言できますが、基本の考え方は同じです。