この記事の要点
• static メンバーはクラスに紐づき、インスタンス不要で使える
• final フィールドは一度代入したら変更不可(定数)
• `public static final` で 大文字スネークケース の定数を定義する
このシリーズについて
「Java入門」は1本1テーマで進むシリーズです。本記事は第25回(最終回)として、static と final の基本を扱います。
前提条件: Java入門 #4 - クラスとオブジェクト、Java入門 #6 - メソッド を読んでいること。クラス・フィールド・メソッドの理解が必要です。
static とは
通常のフィールドやメソッドは インスタンスごと に存在します。一方、static を付けたメンバーは クラス全体で1つ だけ存在し、インスタンスを作らなくても使えます。
| 種類 | 紐づく対象 | 呼び出し方 |
|---|---|---|
| インスタンスメンバー | 各インスタンス | obj.method() |
| static メンバー | クラス全体 | ClassName.method() |
static フィールド(クラス変数)
すべてのインスタンスで共有される変数です。
// Counter.java
public class Counter {
public static int count = 0; // static フィールド
private String name;
public Counter(String name) {
this.name = name;
count++; // インスタンスが作られるたびに +1
}
public void showInfo() {
System.out.println(name + " / 合計: " + count + "個");
}
}
// Main.java(Java 21)
public class Main {
public static void main(String[] args) {
Counter c1 = new Counter("A");
c1.showInfo(); // → A / 合計: 1個
Counter c2 = new Counter("B");
c2.showInfo(); // → B / 合計: 2個
Counter c3 = new Counter("C");
c3.showInfo(); // → C / 合計: 3個
System.out.println("総数: " + Counter.count); // → 総数: 3
}
}
count は static なので、すべての Counter インスタンスで 同じ変数を共有 します。
ポイント: static フィールドは「クラス全体で1つだけの値」を保持したいときに使います。例: ログイン中のユーザー数、次に割り振るID など。
static メソッド(クラスメソッド)
インスタンスを作らずに呼べるメソッドです。Math.max(), Math.sqrt() などが代表例です。
// MathUtils.java
public class MathUtils {
// static メソッド
public static int square(int n) {
return n * n;
}
public static double average(double a, double b) {
return (a + b) / 2.0;
}
}
// Main.java
public class Main {
public static void main(String[] args) {
int result = MathUtils.square(5); // インスタンス不要
System.out.println(result); // → 25
double avg = MathUtils.average(10.0, 20.0);
System.out.println(avg); // → 15.0
}
}
MathUtils のインスタンスを作らず、MathUtils.square(5) のように クラス名.メソッド名 で呼びます。
注意: static メソッドの中では、インスタンスフィールドやインスタンスメソッドを直接使えません。あくまで「クラスレベル」の処理だけを書きます。
static の用途まとめ
| 用途 | 例 |
|---|---|
| ユーティリティメソッド | Math.max(), Arrays.sort(), Collections.shuffle() |
| ファクトリーメソッド | LocalDate.now(), List.of() |
| 定数 | Math.PI, Integer.MAX_VALUE |
| シングルトンパターン | getInstance() で唯一のインスタンスを返す |
final とは
final キーワードは 「変更不可」 を表します。フィールド・メソッド・クラスに付けられます。
| 付ける場所 | 意味 |
|---|---|
| フィールド | 一度代入したら変更できない(定数) |
| メソッド | サブクラスでオーバーライドできない |
| クラス | 継承できない(final class String など) |
final フィールド(定数)
一度値を代入したら、二度と変更できません。
// Circle.java
public class Circle {
private final double radius; // final フィールド
public Circle(double radius) {
this.radius = radius; // コンストラクタで一度だけ代入
}
public double getArea() {
return Math.PI * radius * radius;
}
public void setRadius(double r) {
// this.radius = r; // コンパイルエラー!
// → Cannot assign a value to final variable 'radius'
}
}
final フィールドは コンストラクタまたは宣言時に初期化 しなければなりません。
public class Example {
private final int value = 100; // 宣言時に初期化
private final String name;
public Example(String name) {
this.name = name; // コンストラクタで初期化
}
}
学習のヒント: `final` を付けると「後から変更されない」ことが保証されるので、バグを防ぎやすくなります。可能な限り `final` を付ける習慣をつけましょう。
public static final による定数定義
定数は public static final の3つを組み合わせて宣言します。
// Constants.java
public class Constants {
public static final double TAX_RATE = 0.10; // 消費税率
public static final int MAX_RETRY = 3; // 最大リトライ回数
public static final String APP_NAME = "MyApp";
}
// Main.java
public class Main {
public static void main(String[] args) {
double price = 1000.0;
double total = price * (1 + Constants.TAX_RATE);
System.out.println("合計: " + total); // → 合計: 1100.0
}
}
| 修飾子 | 意味 |
|---|---|
public | どこからでもアクセスできる |
static | クラスに紐づく(インスタンス不要) |
final | 変更不可(定数) |
定数の命名規則
Java の定数は 大文字スネークケース(UPPER_SNAKE_CASE)で書くのが慣習です。
| 種類 | 命名規則 | 例 |
|---|---|---|
| 変数・フィールド | キャメルケース | userName, maxRetry |
定数(static final) | 大文字スネークケース | TAX_RATE, MAX_RETRY, APP_NAME |
| クラス名 | パスカルケース | Counter, MathUtils |
| メソッド名 | キャメルケース | getName(), setAge() |
ポイント: 定数をまとめた専用クラス(`Constants.java`)を作ると、プロジェクト全体で値を一元管理できます。
final メソッド・final クラス(軽く)
final メソッド
final を付けたメソッドは、サブクラスでオーバーライドできません。
public class Parent {
public final void show() {
System.out.println("変更不可のメソッド");
}
}
public class Child extends Parent {
@Override
public void show() { // コンパイルエラー!
// → 'show()' cannot override 'show()' in 'Parent'; overridden method is final
}
}
final クラス
final を付けたクラスは継承できません。
public final class Immutable {
// このクラスは継承できない
}
public class Sub extends Immutable { // コンパイルエラー!
// → Cannot inherit from final 'Immutable'
}
Java 標準ライブラリでは String, Integer, Math などが final class です。
static と final の組み合わせまとめ
| 組み合わせ | 意味 | 例 |
|---|---|---|
static のみ | クラス変数・クラスメソッド(変更可) | Counter.count++ |
final のみ | インスタンスごとに値は違うが変更不可 | private final double radius |
static final | クラス全体で1つの定数 | public static final double PI = 3.14 |
実践例: 定数とユーティリティクラス
// Config.java(定数クラス)
public class Config {
public static final String APP_NAME = "MyApp";
public static final String VERSION = "1.0.0";
public static final int TIMEOUT_SECONDS = 30;
private Config() {
// インスタンス化を防ぐ(ユーティリティクラスの慣習)
}
}
// StringUtils.java(ユーティリティクラス)
public class StringUtils {
// インスタンス化を防ぐ
private StringUtils() {}
public static boolean isEmpty(String s) {
return s == null || s.isEmpty();
}
public static String repeat(String s, int count) {
return s.repeat(count); // Java 11+
}
}
// Main.java
public class Main {
public static void main(String[] args) {
System.out.println(Config.APP_NAME + " v" + Config.VERSION);
// → MyApp v1.0.0
String str = "Hello";
System.out.println(StringUtils.repeat(str, 3));
// → HelloHelloHello
}
}
注意: ユーティリティクラス(すべてが static メソッド)は、`private` コンストラクタでインスタンス化を防ぐのが慣習です。
まとめ
| 概念 | 説明 |
|---|---|
| static フィールド | クラス全体で1つの変数。すべてのインスタンスで共有 |
| static メソッド | インスタンス不要で呼べるメソッド。ClassName.method() |
| final フィールド | 一度代入したら変更不可。定数や不変オブジェクトで使う |
| final メソッド | サブクラスでオーバーライド不可 |
| final クラス | 継承不可(String, Integer など) |
| public static final | クラス全体で1つの定数。大文字スネークケースで命名 |
次のステップ(本シリーズ完結)
「Java入門」シリーズはここで完結です。お疲れさまでした。
ここまでで Java の基礎文法、クラス設計、継承・インターフェース、例外処理、コレクション、ジェネリクス、ラムダ式まで一通り学びました。次のステップとして以下の学習方向があります。
実務で使うフレームワーク・ツール
- Spring Boot — Java で Web アプリ・REST API を作る定番フレームワーク
- JUnit 5 — 単体テストを書く標準ライブラリ
- Maven / Gradle — ビルドツール・依存関係管理
- Lombok — ボイラープレートコードを減らすライブラリ
さらに深める領域
- 並行処理 — スレッド、
Executor、仮想スレッド(Java 21+) - ストリーム API 応用 — 複雑なデータ変換、並列ストリーム
- モジュールシステム — Java 9+ のモジュール(
module-info.java) - デザインパターン — GoF の23パターン(Singleton, Factory, Strategy など)
このサイトでは今後、Spring Boot 入門や JUnit 入門のシリーズを公開予定です。引き続き学習を続けてください。
参考リソース
- Class Variables(Oracle Java Tutorial) — static の公式ガイド
- Final Variables(Oracle) — final の解説
- Effective Java 第3版 — Java のベストプラクティス集(英語)
- Java SE 21 ドキュメント