Java中的构造函数可以是私有的吗?

Raj*_*esh 219 java constructor private

构造函数可以是私有的吗?私有构造函数如何有用?

Mic*_*yan 146

是的,构造函数可以是私有的.这有不同的用途.一个这样的用途是单一设计反模式,我建议反对你使用.另一个更合理的用途是委托构造函数; 你可以有一个构造函数,它有很多不同的选项,实际上是一个实现细节,所以你把它设为私有,但是你剩下的构造函数会委托给它.

作为委托构造函数的示例,以下类允许您保存值和类型,但它只允许您为类型的子集执行此操作,因此需要使通用构造函数为private,以确保仅使用允许的类型.公共私有构造函数有助于代码重用.

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

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

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

     public String toString(){
         return value;
     }

     public String getType(){
         return type;
     }

     private MyClass(String value, String type){
         this.value = value;
         this.type = type;
     }
}
Run Code Online (Sandbox Code Playgroud)

编辑
从几年后看这个答案,我想指出,这个答案既不完整又有点极端.单身人士确实是一种反模式,一般应尽可能避免; 然而,除了单身人士之外,私人建设者还有很多用途,而我的答案只有一个.

给出一些使用私有构造函数的案例:

  1. 创建一个只能是相关静态函数集合的不可实例化的类(这基本上是一个单例,但如果它是无状态的,静态函数严格依赖于参数而不是类状态,这不像我的方法那样不合理早期的自我似乎暗示,尽管使用依赖注入的接口通常使得在实现需要大量依赖关系或其他形式的上下文时更容易维护API.

  2. 当有多个不同的方式来创建对象,一个私有的构造可能更容易理解其构建方式的不同(例如,这将更加有可读性,你new ArrayList(5)还是ArrayList.createWithCapacity(5),ArrayList.createWithContents(5),ArrayList.createWithInitialSize(5)).换句话说,私有构造函数允许您提供其名称更易理解的工厂函数,然后使构造函数私有,确保人们只使用更不言而喻的名称.这也常用于构建器模式.例如:

    MyClass myVar = MyClass
        .newBuilder()
        .setOption1(option1)
        .setOption2(option2)
        .build();
    
    Run Code Online (Sandbox Code Playgroud)

  • 这里真正的反模式是过度使用imho.这适用于任何习惯使用的模式,而不考虑在给定情况下最佳的模式. (23认同)
  • @Vuntic,简短的回答是单身人士会导致共享的可变状态,更重要的是,将单身人士加入到API中会使其变得不灵活,难以测试,并且当事实证明单身假设时会让人感觉很糟糕是不正确的.虽然你只需要实例化一次对象就可以拥有单例,但通过私有构造函数和静态实例化函数强制执行单例操作会导致一个令人难以置信的混乱和脆弱的设计.更好的方法是传递单例符合的接口... (13认同)
  • 从可测试性的角度来看 - 它们代表了一个很难预测(和测试)的全局状态 (7认同)
  • ...并且只构造它的一个实例,然后传递它.这种方法称为依赖注入,可以实现更清晰,更灵活的设计. (7认同)
  • 所以... Google Joshua Bloch的前任首席Java架构师提倡使​​用私有构造函数的静态工厂方法(Effective Java 2nd edition)...考虑到他对语言的专业知识和他创建的Java Collections Framework,我会说私人构造函数旁边静态工厂方法是非常可行和推荐使用的私有构造函数 (5认同)
  • @MuhammadBabar,我相信我回答了这个问题,但重申一下......你保证在课堂外只有一个实例.也就是说,您只构造一个实例,然后将该实例传递给所有使用它的地方(而不是在类的任何地方调用静态getInstance函数).这可以手动完成或使用依赖注入框架完成. (2认同)

Boz*_*zho 92

我希望有人会提到这个(第二点),但是......私有构造函数有三种用法:

  • 在以下情况下,防止在对象外部进行实例化:

    • 独生子
    • 工厂方法
    • static-methods-only(实用程序)类
    • 常数类
      .
  • 防止下沉(延伸).如果只创建一个私有构造函数,则没有类可以扩展您的类,因为它无法调用super()构造函数.这是某种同义词final

  • 重载的构造函数 - 由于重载方法和构造函数,一些可能是私有的,一些是公共的.特别是在您在构造函数中使用非公共类的情况下,您可以创建一个公共构造函数,该构造函数创建该类的实例,然后将其传递给私有构造函数.

  • 没有必要,但你可以.我提到了`final`关键字作为实现这一目标的一种方式. (11认同)
  • 在Java中,关键字"final"用于防止子类化; 没有必要将构造函数设为私有. (8认同)

Fea*_*nor 25

是的,它可以.将存在私有构造函数以防止实例化类,或者因为构造仅在内部发生,例如工厂模式.有关更多信息,请参见此处


lav*_*nio 16

是.

这样您就可以控制类的实例化方式.如果您将构造函数设为私有,然后创建一个返回类的实例的可见构造函数方法,则可以执行诸如限制创建数量(通常保证只有一个实例)或回收实例或其他与构造相关的任务的操作.

否则new x()永远不会返回null,但使用工厂模式,可以退货null,甚至返回不同的亚型.

您也可以将它用于没有实例成员或属性的类,只使用静态成员 - 就​​像在实用程序函数类中一样.


lic*_*nbo 9

好吧,如果一个类中的所有方法都是静态的,那么私有构造函数是个好主意.


Abh*_*iya 8

是的。类可以有私有构造函数。即使抽象类也可以有私有构造函数。

通过将构造函数设为私有,我们可以防止类被实例化以及该类的子类化。

以下是私有构造函数的一些用途:

  1. 单例设计模式
  2. 限制实例创建次数
  3. 使用静态工厂方法为对象创建赋予有意义的名称
  4. 静态实用程序类或常量类
  5. 防止子类化
  6. 构建器设计模式,从而创建不可变的类


gmh*_*mhk 6

私有构造函数可以在Java中进行定义,原因如下

  1. 要控制Java对象的实例化,它不允许您创建对象的实例.

  2. 它不允许该类被Subclassed

  3. 这在实现单例模式时具有特殊优势,使用私有协作器并且可以控制为整个应用程序创建实例.

  4. 当你想要一个定义了所有常量的类并且不再需要它的实例时,我们将该类声明为私有构造函数.


ryf*_*059 5

是.

私有构造函数用于防止实例初始化,例如您在java中使用的Math final类.Singleton也使用私有构造函数