広告

手を動かして学ぶ Java入門 (静的フィールド)

環境構築不要! ブラウザから直接コードを実行できます。
本記事では、クラスの静的フィールド (staticフィールド) について学びます。

10分くらいで、さくっと終わる記事をめざしています。


シリーズ一覧

続きは近日公開予定!

はじめに

この記事は paiza.IO の「Online Java compiler」を利用しています。
2024/11/18 現在、上記環境の Java バージョンは 18 です。(paiza.IO利用ガイド)

実行したコードは paiza.IO で保存および公開されることがあります。
そのため、個人情報などの機密性の高い情報は、コードとして入力しないようにご注意ください。

詳細は paiza.IO の利用規約およびプライバシーポリシーをご確認ください。

フィールドのおさらい

オブジェクト指向プログラミングでは、フィールドはクラスや構造体などに直接宣言される任意の型の変数であり[3]、オブジェクト内にカプセル化されたデータである。

フィールドとは、クラスのインスタンスが持つ 変数 のことです。
Java 以外の言語では「メンバ変数」と呼ばれることもあります。

以前の記事 でも学習しましたね。

フィールドの大事な特徴の1つに、

  • フィールドは インスタンス毎に独立 して生成される

という点があります。

次の Sample クラスを例に見てみましょう。

public class Sample {
    private int value;

    public void increment() {
        value++;
    }

    public void print() {
        System.out.println("value = " + value);
    }
}

Sample クラスには、value という名前のフィールドがあります。

Sample sample1 = new Sample();
Sample sample2 = new Sample();

sample1.increment();
sample1.increment();
sample2.increment();

sample1.print();
sample2.print();

Sample クラスのインスタンスを

  • sample1
  • sample2

と2つ生成しているのがポイントですね。

そして、

  • sample1increment メソッドを2回
  • sample2increment メソッドを1回

呼び出しています。

それでは、実際にコードを動かしてみましょう。
結果がどうなるか予想してから「実行(Ctrl-Enter)」ボタンを押してください。

注意:コードは2ファイルあります。上部のタブで切り替え可能です。

タブ

(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)

いかがでしたでしょうか? 「出力」のところに

value = 2
value = 1

と表示されたら成功です。

イメージ1

sample1sample2 は、それぞれ別で管理されている value フィールドを持ちます。
よって、increment メソッドを呼び出しても、それぞれのインスタンスの value だけが +1 されるわけですね。

静的フィールド

静的フィールドとは、インスタンスではなく クラスが持つ 変数です。
つまり インスタンス は必要ありません。

また、インスタンスを必要としないので 静的メソッド からもアクセスできます。

例を見てみましょう。
まずは静的メソッドから 通常のフィールド にアクセスしてみます。

public class Sample {
    private int value; 

    public static void set(int v) {
        value = v;
    }

    public static void print() {
        System.out.println("value = " + value);
    }
}

Sample クラスは通常のフィールドである value を宣言しています。
set メソッドと print メソッドは静的メソッドです。

Sample.set(123);
Sample.print();

静的メソッドの呼び出しは、こんな感じですね。

それでは、実際に確認してみましょう。
コードは変更せずに、そのまま「実行(Ctrl-Enter)」ボタンを押してください。

注意:コードは2ファイルあります。上部のタブで切り替え可能です。

タブ

(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)

いかがでしたでしょうか? 

Sample.java:5: error: non-static variable value cannot be referenced from a static context
        value = v;
        ^
Sample.java:9: error: non-static variable value cannot be referenced from a static context
        System.out.println("value = " + value);
                                        ^

とエラーになれば成功です。

"non-static variable name cannot be referenced from a static context" は意訳すると…

  • static ではないフィールド(変数) は、静的メソッドからはアクセスできません

という感じですね。


次は、Sample クラスの value フィールドを、静的フィールドに変えてみましょう。

先ほどの Sample クラスを…

public class Sample {
    private int value;
    ^^^^^^^^^^^^^^^^^^ ← この部分!
    ...
}

次のように書き換えてください。

public class Sample {
    private static int value;
            ^^^^^^ ← これを追加
    ...
}

static キーワードをつけることで、フィールドは静的になります。

それは、static キーワードを書き加えてから「実行(Ctrl-Enter)」ボタンを押してください。

注意:コードは2ファイルあります。上部のタブで切り替え可能です。

タブ

(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)

いかがでしたでしょうか? 「出力」のところに

value = 123

と表示されたら成功です。

無事に、インスタンスなしでクラスのフィールドにアクセスできました。

イメージ2

宣言

静的フィールドを使うためにはクラスで宣言する必要があります。

public class Sample {
    private static int value; // 静的フィールドの宣言!

    ...
}

静的フィールド宣言の基本は

  • アクセス修飾子 + static + 変数の型 + 変数名

となります。

private static int value;
^^^^^^^ <--- アクセス修飾子
private static int value;
        ^^^^^^ <--- staticキーワード
private static int value;
               ^^^ <--- 変数の型
private static int value;
                   ^^^^^ <--- 任意の変数名

※ アクセス修飾子の前に static を書くこともできますが、一般的ではないためおすすめしません。

注意点

静的フィールドの主な用途は、

  • 定数を定義

することです。
(定数については、長くなりそうなので次回解説予定です)

それ以外の用途で安易に使うのはおすすめしません。

もう1度いいます。
定数以外の用途で静的フィールドを使うのはおすすめしません

難しい話になるので詳細は割愛しますが、うまく使わないと グローバル変数 と同じ問題をかかえるためです。

慣れるまでは、静的フィールドは定数の定義にだけ使うのが無難でしょう。


応用問題

【問題】

まずは、下記のプログラムをそのまま「実行(Ctrl-Enter)」してみましょう。
「出力」には、

-- sample1 --
value1 = 1 : value2 = 1
-- sample2 --
value1 = 2 : value2 = 2

と表示されたはずです。

そこで問題です。

Sample クラスのどこかに static キーワードを書き加えて、結果が

-- sample1 --
value1 = 1 : value2 = 3
-- sample2 --
value1 = 2 : value2 = 3

となるようにしてください。
書き加えてよいのは static だけです。

【ヒント】

  • 静的フィールドは、クラス自身が持つフィールドです。
    つまり、インスタンス毎に独立はしていません

それでは、static を書き加えてから「実行(Ctrl-Enter)」してみましょう。

注意:コードは2ファイルあります。上部のタブで切り替え可能です。

タブ

(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)

無事に、

-- sample1 --
value1 = 1 : value2 = 3
-- sample2 --
value1 = 2 : value2 = 3

と出力されましたでしょうか?

もし解けなかった場合は、下記の回答例をご参照ください。

回答例

【コード】

public class Sample {
    private int value1;
    private static int value2;

    public void increment() {
        value1++;
        value2++;
    }

    public void print() {
        System.out.println("value1 = " + value1 + " : value2 = " + value2);
    }
}

※ Main.java は書き換えません。

【出力】

-- sample1 --
value1 = 1 : value2 = 3
-- sample2 --
value1 = 2 : value2 = 3

まとめ

本記事では、クラスの静的フィールドについて解説しました。

静的フィールドとは、インスタンスではなく クラスが持つ 変数です。
つまり インスタンス は必要ありません。

ただし、定数の定義以外で安易に使うのはおすすめしません。
グローバル変数と同じ問題をかかえることがあるからです。

それでは次回もお楽しみに! (次回は定数の定義の解説を予定しています)


関連記事

ページの先頭へ