web-dev-qa-db-ja.com

コンストラクタは常にパブリックである必要がありますか?

私の最初の質問は-

   class Explain() {
        public Explain() {
      }
   }

コンストラクタは常にパブリックとして宣言する必要がありますか?

privateコンストラクターを作成するとどうなりますか。

コンストラクターが暗黙的にpublicであるのを見てきました。では、なぜprivateコンストラクターが便利なのでしょうか?または、まったく役に立ちません。誰もそれを呼び出せないか、オブジェクトを作成できない(privateコンストラクターのため)!それが私の2番目の質問です。

49
Hash Leon

いいえ、Constructorspublicprivateprotected、またはdefaultにできます(アクセス修飾子はまったくありません)。

privateを作成しても、だれもアクセスできないわけではありません。クラス外の誰もアクセスできないことを意味します。したがって、privateコンストラクタも便利です。

privateコンストラクターの使用の1つは、シングルトンクラスを提供することです。シングルトンクラスは、オブジェクトの作成数を1つに制限するクラスです。 privateコンストラクターを使用すると、一度に複数のオブジェクトを作成できないようにすることができます。

例-

public class Database {

    private static Database singleObject;
    private int record;
    private String name;

    private Database(String n) {
        name = n;
        record = 0;
    }

    public static synchronized Database getInstance(String n) {
        if (singleObject == null) {
            singleObject = new Database(n);
        }

        return singleObject;
    }

    public void doSomething() {
        System.out.println("Hello StackOverflow.");
    }

    public String getName() {
        return name;
    }
}

に関する詳細情報 アクセス修飾子

75
Dhanuka

はい、コンストラクタは任意のアクセス指定子/アクセス修飾子を持つことができます。

プライベートコンストラクターは、singletonクラスの作成に役立ちます。

シングルトン-シングルトンクラスは、実行時に(JVMごとに)単一のオブジェクトのみを作成できるクラスです。

シングルトンクラスの簡単な例は-

class Ex {
    private static Ex instance;
    int a;
    private Ex() {
        a = 10;
    }
    public static Ex getInstance() {
        if(instance == null) {
            instance = new Ex();
        }
        return instance;
    }
}

上記のクラスの場合、オブジェクト(このクラス外)を取得する唯一の方法はgetInstance()関数を呼び出すことです。これは単一のインスタンスのみを作成し、それを返し続けます。

また、これはスレッドセーフではないことに注意してください。

9
Anand S Kumar

コンストラクタは、パブリック、デフォルト、プライベートのいずれでもかまいませんが、すべてはコンストラクタで何をしたいかによって異なります。

たとえば、シングルトンクラスを定義している場合は、hideをお勧めします(プライベートにすると、クラスでのみ使用できるようになります)属する)他のクラスが自分の意志でクラスをインスタンス化するのを防ぐコンストラクタ。

同じパッケージ内のテストケースがアクセスできるように、テスト目的でデフォルトとして宣言することができます。

より詳細な情報が見つかりました こちら

7
Alp

コンストラクタがパブリックであるというルールはありません。一般に、他のクラスからもインスタンス化したいという理由だけで、パブリックとして定義します。

プライベートコンストラクターとは、「私以外の誰にもインスタンスを作成させない」という意味です。そのため、通常、シングルトンパターンが必要なときにこれを行います。

以下は、プライベートコンストラクターを使用するJDKのクラスです。

public class Runtime {
    private static Runtime currentRuntime = new Runtime();

    public static Runtime getRuntime() {
        return currentRuntime;
    }

    // Don't let anyone else instantiate this class
    private Runtime() {
    }
}
5
Aston Ray

いいえ、コンストラクタはプライベートを含む任意のアクセス修飾子を使用できます。 (プライベートコンストラクターは、クラス自体内のコードのみがそのタイプのオブジェクトをインスタンス化できることを意味するため、プライベートコンストラクタークラスがクラスのインスタンスの使用を許可する場合、クラスは、クラス内から作成されたインスタンス。)

class Alpha {
   static String s = " ";
   protected Alpha() { s += "alpha "; }
 }
 class SubAlpha extends Alpha {
   private SubAlpha() { s += "sub "; }
 }
 public class SubSubAlpha extends Alpha {
   private SubSubAlpha() { s += "subsub "; }
   public static void main(String[] args) {
     new SubSubAlpha();
     System.out.println(s);
   }
 }

上記のプログラムの出力は

アルファサブサブ

5
Nitesh Soomani

コンストラクターは、あらゆる種類のアクセス修飾子を持つことができます。コンストラクターでの異なるアクセス修飾子の使用法は異なります。

どこからでもクラスをインスタンス化する場合は、コンストラクターpublicを作成します。

クラスを継承し、その継承クラスをインスタンス化する場合は、コンストラクターprotectedを作成します。

通常は静的ブロックまたは静的メソッドである独自のメンバーからクラスをインスタンス化する場合は、コンストラクターprivateを作成します。つまり、クラスのインスタンス化を制御し、インスタンス化に何らかのルールを適用します。プライベートコンストラクターの使用例は、シングルトンデザインパターンです。

4
A.v

シングルトンはプライベートコンストラクターを持つクラスの良い例であるという以前の回答に同意します。私は別の実装を推奨します:スレッドセーフシングルトン:

/**
 * Thread safe singleton
 */
public class Singleton {

    private static volatile Singleton instance = null;

    /**
     * Private constructor
     */
    private Singleton() {
    }

    /**
     * Gets the Instance of the Singleton in a thread safe way.
     * @return
     */
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

スレッドセーフな方法でシングルトンを使用すると、並列コードの多くの痛みを防ぐことができます。

4
Marc Giombetti

コンストラクタhasは、たとえば、次のようなカスタムファクトリクラスの作成中に、少なくとも保護され、さらにはプライベートになります。

public final class MyFactory {
  private MyFactory(){} // this one prevents instances of your factory
}

public static void doSomething(){} // access that with MyFactory.doSomething

これは、コンストラクターをパブリックにしない場合を示す1つの例にすぎないことに注意してください。

3
Arthur Eirich

他の人は、コンストラクタにはアクセス修飾子があるかもしれないと指摘しています。まだ言及されていない側面は、コンストラクターの側面修飾子が構築の2つのまったく異なる側面を制御しますが、それらを個別に制御することは許可しないということです。

  1. ClassNameのインスタンスのインスタンスを作成できるユーザーと、使用できるコンストラクター。
  2. 誰がClassNameextensionsを作成でき、どのコンストラクタを使用できるか。

両方のJavaと.NETでは、これら2つの質問に対する答えが一緒になっている必要があります;クラスがfinal(またはsealed)ではなく、コンストラクターを許可する場合新しいインスタンスを作成するために外部コードによって使用される場合、外部コードは派生型を作成するために同じコンストラクターを使用する自由もあります。

多くの場合、クラスがパッケージプライベート(internal)コンストラクターのみを持ち、新しいインスタンスを返すパブリックメソッドを公開することが適切な場合があります。そのようなアプローチは、Stringのようなタイプをゼロから設計している場合に使用できます。 Stringを含むパッケージはそれを抽象型として定義できますが、コンテンツを_UCS16String_および_byte[]_として保存するAsciiStringや_Char[]_などの具象派生型を含めることができます。それぞれ; Stringを返すメソッドは、文字列にASCIIの範囲外の文字が含まれているかどうかによって異なります。Stringも派生型もコンストラクタを公開しない場合、パッケージ外で、パッケージ内のすべての派生型が文字列として動作することが期待される場合、String型の参照を受け取るコードは、文字列として正常に動作することを期待できます(たとえば、ただし、パッケージの外部でコンストラクタを公開すると、派生型が奇妙で奇妙な動作をすることが可能になります(たとえば、検証および検証後に内容を変更するなど)。

構文の観点から、Fnord foo = new Fnord(123);と言うことができることはFnord foo = Fnord.Create(123);と言うよりも少しいいですが、後者の構文を必要とするクラスFnordははるかに優れた制御を維持できます。オブジェクト作成プロセスで。

1
supercat

これらの回答のほとんどは、シングルトンまたはファクトリクラスを参照しています。 (たとえば) Java.lang.Math class にプライベートコンストラクターが表示される場合、すべてが静的であり、誰もコンストラクター(クラス自体を含む)を呼び出すべきではありません。プライベートコンストラクターを持つことにより、クラス外のユーザーがコンストラクターを呼び出さないようにします。 (これは、クラス内の誰かがコンストラクターを呼び出すことを妨げるものではありませんが、その後、独自のルールを破っています。)

1
Teepeemm

簡単な説明は、クラスにコンストラクターがない場合、コンパイラーは自動的にデフォルトのコンストラクターを作成します。

コンストラクターは常にパブリックとして宣言されるわけではなく、プライベート、保護、またはデフォルトにすることもできます。

プライベートコンストラクターは、クラスが呼び出し側によって完全かつ明確に表現/表現されるのを防ぎます。その場合、プライベートコンストラクターが便利です。クラスをサブクラス化する必要がない場合は、プライベートコンストラクターを使用できます。

0
Nimishan