1. 序章

プライベートコンストラクターを使用すると、クラスのインスタンス化を制限できます。 簡単に言えば、クラス自体以外の場所でのクラスインスタンスの作成を防ぎます。

パブリックコンストラクターとプライベートコンストラクターを一緒に使用すると、クラスをインスタンス化する方法を制御できます。これは、コンストラクター委任と呼ばれます。

2. 典型的な使用法

明示的なクラスのインスタンス化を制限することにはいくつかのパターンと利点があり、このチュートリアルでは最も一般的なものを見ていきます。

プライベートコンストラクターを定義する方法を見てみましょう。

public class PrivateConstructorClass {
    
    private PrivateConstructorClass() {
        // in the private constructor
    }
}

パブリックコンストラクターと同様にプライベートコンストラクターを定義します。 publicキーワードをprivateに変更しただけです。

3. シングルトンパターンでのプライベートコンストラクターの使用

シングルトンパターンは、プライベートコンストラクターの使用に遭遇する最も一般的な場所の1つです。 プライベートコンストラクターを使用すると、クラスのインスタンス化を単一のオブジェクトインスタンスに制限できます。

public final class SingletonClass {
    
    private static SingletonClass INSTANCE;
    private String info = "Initial info class";

    private SingletonClass() {
    }

    public static SingletonClass getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new SingletonClass();
        }

        return INSTANCE;
    }

    // getters and setters
}

SingletonClass.getInstance()を呼び出すことでインスタンスを作成できます。これにより、既存のインスタンスが返されるか、これが最初のインスタンス化である場合はインスタンスが作成されます。 このクラスをインスタンス化するには、 getInstance()静的メソッドを使用する必要があります。

4. プライベートコンストラクタを使用してコンストラクタを委任する

プライベートコンストラクターのもう1つの一般的な使用例は、コンストラクター委任の手段を提供することです。 コンストラクターの委任を使用すると、初期化を特定の場所に制限しながら、いくつかの異なるコンストラクターを介してパラメーターを渡すことができます

この例では、 ValueTypeClass は値とタイプを使用した初期化を許可しますが、タイプのサブセットに対してのみ許可する必要があります。 許可された型のみが使用されるようにするには、一般的なコンストラクターをプライベートにする必要があります。

public class ValueTypeClass {
    
    private final String value;
    private final String type;

    public ValueTypeClass(int x) {
        this(Integer.toString(x), "int");
    }

    public ValueTypeClass(boolean x) {
        this(Boolean.toString(x), "boolean");
    }

    private ValueTypeClass(String value, String type) {
        this.value = value;
        this.type = type;
    }

    // getters and setters
}

ValueType Class は、2つの異なるパブリックコンストラクターを介して初期化できます。1つは int を受け入れ、もう1つはbooleanを受け入れます。 次に、これらの各コンストラクターは、共通のプライベートコンストラクターを呼び出して、オブジェクトの初期化を完了します。

5. プライベートコンストラクタを使用してインスタンス化できないクラスを作成する

インスタンス化できないクラスは、インスタンス化できないクラスです。 この例では、静的メソッドのコレクションを含むクラスを作成します。

public class StringUtils {
    
    private StringUtils() {
        // this class cannot be instantiated
    }

    public static String toUpperCase(String s) {
        return s.toUpperCase();
    }

    public static String toLowerCase(String s) {
        return s.toLowerCase();
    }
}

StringUtils クラスには、いくつかの静的ユーティリティメソッドが含まれており、プライベートコンストラクターのためにインスタンス化できません。

実際、静的メソッドではオブジェクトインスタンスを使用する必要がないため、オブジェクトのインスタンス化を許可する必要はありません。

6. Builderパターンでのプライベートコンストラクターの使用

ビルダーパターンを使用すると、オブジェクトを作成するためのさまざまな方法を提供する複数のコンストラクターを使用するのではなく、複雑なオブジェクトを段階的に作成できます。 プライベートコンストラクターは初期化を制限し、ビルダーが代わりにオブジェクト作成を管理できるようにします

この例では、従業員の name age 、およびdepartmentを保持するEmployeeクラスを作成しました。

public class Employee {

    private final String name;
    private final int age;
    private final String department;

    private Employee(String name, int age, String department) {
        this.name = name;
        this.age = age;
        this.department = department;
    }
}

ご覧のとおり、 Employee コンストラクターをプライベートにしたため、クラスを明示的にインスタンス化することはできません。

次に、内部のBuilderクラスをEmployeeクラスに追加します。

public static class Builder {

    private String name;
    private int age;
    private String department;

    public Builder setName(String name) {
        this.name = name;
        return this;
    }

    public Builder setAge(int age) {
        this.age = age;
        return this;
    }

    public Builder setDepartment(String department) {
        this.department = department;
        return this;
    }

    public Employee build() {
        return new Employee(name, age, department);
    }
}

ビルダーは、 name age 、または department でさまざまな従業員を作成できるようになりました。提供する必要のあるフィールドの数に制約はありません:

Employee.Builder emplBuilder = new Employee.Builder();

Employee employee = emplBuilder
  .setName("baeldung")
  .setDepartment("Builder Pattern")
  .build();

baeldung」という名前と「BuilderPattern」の部門を持つEmployeeを作成しました。 年齢は指定されていないため、デフォルトのプリミティブint値0が使用されます。

7. サブクラス化を防ぐためのプライベートコンストラクターの使用

プライベートコンストラクターのもう1つの可能な使用法は、クラスのサブクラス化を防ぐことです。 サブクラスなどを作成しようとすると、スーパーを呼び出せなくなりますコンストラクタ 。 ただし、通常は、プライベートコンストラクターを使用するのではなく、サブクラス化を防ぐためにクラスをfinalにすることに注意してください。

8. 結論

プライベートコンストラクターの主な用途は、クラスのインスタンス化を制限することです。 プライベートコンストラクターは、クラスの外部作成を制限する場合に特に便利です。

シングルトン、ファクトリ、および静的メソッドオブジェクトは、オブジェクトのインスタンス化を制限することが特定のパターンを適用するのにどのように役立つかを示す例です。

定数クラスと静的メソッドクラスも、クラスをインスタンス化できないようにすることを指示します。 プライベートコンストラクターとパブリックコンストラクターを組み合わせて、さまざまなパブリックコンストラクター定義内でコードを共有できることを覚えておくことが重要です。

これらの例のコードは、GitHubにあります。