0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaのEnum ~Singletonパターンを添えて~

Last updated at Posted at 2025-08-12

はじめに

Sigletonパターン(GoFデザインパターン)について学習していた際に、Enumを使うやり方があったので、Enumについてさらっと復習しつつ、Singletonパターンについてほんの少々触れようと思います。
本記事ではしっかりまとめることはしていません。Enum, Singletonパターンについてなんとな~く知りたい方向けになります。
また、私自身が勉強中ですので、何か間違っていましたら教えていただけると嬉しいです。

まず、Enumの基本の基本

関連する複数の定数を、列挙子としてまとめて定義できるクラスが、Enum(列挙型)です。
コード全体の整理がしやすく、間違った値を使うリスクも減り、型安全性も向上するというメリットがあります。

さっそく、スポーツ関連の定数をまとめて定義してみます。

public enum SPORTS {
    SOCCER,
    BASKETBALL,
    TENNIS
}

ここで定義した定数を、このようにして呼び出すことができます。

public class Main {
    public static void main(String[] args) {
        System.out.println(SPORTS.SOCCER);
    }
}
// 出力: SOCCER

switch文で使う

Enumといえばswitch文かもしれませんね。
Enumを使えば、switch文の条件分岐を非常にわかりやすく記述することができます。

public class Main {
    public static void main(String[] args) {
        hoge(SPORTS.SOCCER);
    }

    protected static void hoge(SPORTS sportsType) {
        switch (sportsType) {
            case SOCCER:
                System.out.println("サッカー");
                break;
            case BASKETBALL:
                System.out.println("バスケットボール");
                break;
            default:
                System.out.println("テニス");
        }
    }
}
// 出力: サッカー

フィールドやメソッドの定義

ここからが本題です。
Enumは、関連する複数の定数を、まとめて定義できるクラスなので、フィールドやメソッドを定義することができます。
列挙子に値を付与する場合はフィールドとコンストラクタを定義する必要があるのです。
以下では列挙子に値をもうけ、外からそれにアクセスできるようなgetterメソッドを作ってみました。

SPORTS.java
public enum SPORTS {
    SOCCER("サッカー"),
    BASKETBALL("バスケットボール"),
    TENNIS("テニス");
    
    // フィールド
    private String japanese;
    
    // コンストラクタ
    private SPORTS(String japanese) {
        this.japanese = japanese;
    }
    
    // getterメソッド
    public String getJapanese() {
        return japanese;
    }
}
Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println(SPORTS.SOCCER.getJapanese());
    }
}
// 出力: サッカー

この時、コンストラクタは必ずprivateでないといけません。
なぜなら、Enumの列挙子たちは、それぞれクラスロード時に生成される単一のインスタンスであるからです。
なので、外部からnewして新しくインスタンスを作ることはできないよう、Javaの言語仕様で決まっているのです。

あれ?単一のインスタンスのみしか作れない決まりがあるクラスって、、、

Singletonだ!

ここからSingletonパターンのお話です!
GoFのデザインパターンの中でも、よく使うものとして頻繁に名前の挙がる設計パターンですね。

Singletonパターンというのは、単一のインスタンスのみの生成を保証し、そのインスタンスへグローバルなアクセスを可能にする設計です。
「システム全体でただ一つのインスタンスを作りたい」「唯一の存在であるべきものを作る」という場合に利用されます。例えば、設定や構成情報の管理、ログ管理の場面で活躍するそうです。

デフォルトでコンストラクタはpublicになってしまうので、きちんとprivateで宣言しておきます。

Singleton.java
public class Singleton {
    // 唯一のインスタンス
    private static final Singleton instance = new Singleton();

    // コンストラクタ
    private Singleton() {}

    // インスタンスを返す、外からアクセス可能なメソッド
    public static Singleton getInstance() {
        return instance;
    }

    // 何かの処理をする、外からアクセス可能なメソッド
    public void doSomething() {
        System.out.println("何かの処理");
    }
}
Main.java
public class Main {
    public static void main(String[] args) {
        Singleton.getInstance().doSomething();
    }
}
// 出力: 何かの処理

もう一度、先ほどフィールドとメソッドを定義したEnumの例を考えてみると、そっちでも似たようなことをしていましたよね。privateなフィールドとコンストラクタを定義し、インスタンスに外部からアクセスできるgetterメソッドを作っていました。

Enumの列挙子は単一のインスタンスでしたね。
ということは、これと全く同じことが、Enumで簡単に書けてしまうのではないでしょうか。

EnumでSingletonパターン

Singleton.java
public enum Singleton {
    // 唯一のインスタンス
    INSTANCE;

    // 何かの処理をする、外からアクセス可能なメソッド
    public void doSomething() {
        System.out.println("何かの処理");
    }
}
Main.java
public class Main {
    public static void main(String[] args) {
        Singleton.INSTANCE.doSomething();
    }
}
// 出力: 何かの処理

とても簡単に書けてしまいました。

enumの列挙子はクラスロード時にJVMが自動で唯一のインスタンスを生成します。
そのため、通常のSingletonパターンで必要な「コンストラクタのアクセス制限」が必要ありません。
また、列挙子は外から直接アクセスすることが可能なので、「getInstance()メソッド」も不要になります。

まとめ

EnumとSingletonパターンの基本と、EnumによるSingletonパターンをさらっと見てきました。実際に使っていくためには、それぞれまだまだ深めていく必要がありますが(特にSingletonパターン!)、ひとまず本記事ではここまでにします。

参考にしたサイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?