手を動かして学ぶ Java入門 (静的フィールド)
環境構築不要! ブラウザから直接コードを実行できます。
本記事では、クラスの静的フィールド (staticフィールド) について学びます。
10分くらいで、さくっと終わる記事をめざしています。
シリーズ一覧
- シリーズ
- 手を動かして学ぶ Java入門 (Hello world 編)
- 手を動かして学ぶ Java入門 (数値と演算)
- 手を動かして学ぶ Java入門 (数値と変数)
- 手を動かして学ぶ Java入門 (コメントの書き方)
- 手を動かして学ぶ Java入門 (文と式の違い)
- 手を動かして学ぶ Java入門 (if文)
- 手を動かして学ぶ Java入門 (if-else文、if-elseif文)
- 手を動かして学ぶ Java入門 (文字列の連結)
- 手を動かして学ぶ Java入門 (while文)
- 手を動かして学ぶ Java入門 (break文)
- 手を動かして学ぶ Java入門 (continue文)
- 手を動かして学ぶ Java入門 (for文)
- 手を動かして学ぶ Java入門 (クラスの超基本)
- 手を動かして学ぶ Java入門 (クラス・メソッド)
- 手を動かして学ぶ Java入門 (クラス・フィールド)
- 手を動かして学ぶ Java入門 (クラス・コンストラクタ)
- 手を動かして学ぶ Java入門 (文字列クラス)
- 手を動かして学ぶ Java入門 (静的メソッド)
- 手を動かして学ぶ Java入門 (静的フィールド)
- 手を動かして学ぶ Java入門 (定数の定義)
- 手を動かして学ぶ Java入門 (クラス継承の超基本)
- 手を動かして学ぶ Java入門 (メソッドのオーバーライド)
- 手を動かして学ぶ Java入門 (メソッドのオーバーロード)
続きは近日公開予定!
はじめに
この記事は paiza.IO の「Online Java compiler」を利用しています。
2024/12/17 現在、上記環境の Java バージョンは 18 です。(paiza.IO利用ガイド)
実行したコードは paiza.IO で保存および公開されることがあります。
そのため、個人情報などの機密性の高い情報は、コードとして入力しないようにご注意ください。
詳細は paiza.IO の利用規約およびプライバシーポリシーをご確認ください。
フィールドのおさらい
フィールドとは、クラスのインスタンスが持つ 変数 のことです。
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つ生成しているのがポイントですね。
そして、
- sample1 は increment メソッドを2回
- sample2 は increment メソッドを1回
呼び出しています。
それでは、実際にコードを動かしてみましょう。
結果がどうなるか予想してから「実行(Ctrl-Enter)」ボタンを押してください。
注意:コードは2ファイルあります。上部のタブで切り替え可能です。
(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)
いかがでしたでしょうか? 「出力」のところに
value = 2
value = 1
と表示されたら成功です。
sample1 と sample2 は、それぞれ別で管理されている 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
と表示されたら成功です。
無事に、インスタンスなしでクラスのフィールドにアクセスできました。
宣言
静的フィールドを使うためにはクラスで宣言する必要があります。
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
まとめ
本記事では、クラスの静的フィールドについて解説しました。
静的フィールドとは、インスタンスではなく クラスが持つ 変数です。
つまり インスタンス は必要ありません。
ただし、定数の定義以外で安易に使うのはおすすめしません。
グローバル変数と同じ問題をかかえることがあるからです。
次回は「手を動かして学ぶ Java入門 (定数の定義)」になります。
関連記事
- シリーズ
- 手を動かして学ぶ Java入門 (Hello world 編)
- 手を動かして学ぶ Java入門 (数値と演算)
- 手を動かして学ぶ Java入門 (数値と変数)
- 手を動かして学ぶ Java入門 (コメントの書き方)
- 手を動かして学ぶ Java入門 (文と式の違い)
- 手を動かして学ぶ Java入門 (if文)
- 手を動かして学ぶ Java入門 (if-else文、if-elseif文)
- 手を動かして学ぶ Java入門 (文字列の連結)
- 手を動かして学ぶ Java入門 (while文)
- 手を動かして学ぶ Java入門 (break文)
- 手を動かして学ぶ Java入門 (continue文)
- 手を動かして学ぶ Java入門 (for文)
- 手を動かして学ぶ Java入門 (クラスの超基本)
- 手を動かして学ぶ Java入門 (クラス・メソッド)
- 手を動かして学ぶ Java入門 (クラス・フィールド)
- 手を動かして学ぶ Java入門 (クラス・コンストラクタ)
- 手を動かして学ぶ Java入門 (文字列クラス)
- 手を動かして学ぶ Java入門 (静的メソッド)
- 手を動かして学ぶ Java入門 (静的フィールド)
- 手を動かして学ぶ Java入門 (定数の定義)
- 手を動かして学ぶ Java入門 (クラス継承の超基本)
- 手を動かして学ぶ Java入門 (メソッドのオーバーライド)
- 手を動かして学ぶ Java入門 (メソッドのオーバーロード)