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

2022-08-31 05:37:11

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


答案 1

是的,构造函数可以是私有的。这有不同的用途。一个这样的用途是单设计反模式,我建议你不要使用。另一个更合法的用途是委派构造函数;你可以有一个构造函数,它采用许多不同的选项,这实际上是一个实现细节,所以你把它变成私有的,但你的其余构造函数委托给它。

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

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;
     }
}

编辑
几年后看到这个答案,我想指出这个答案既不完整又有点极端。单例确实是一种反模式,通常应尽可能避免使用;但是,除了单例之外,私有构造函数还有很多用途,我的答案只列出了一个。

再举几个使用私有构造函数的情况:

  1. 要创建一个无法证实的类,它只是相关静态函数的集合(这基本上是一个单例,但如果它是无状态的,并且静态函数严格地在参数而不是类状态上运行,那么这种方法并不像我之前自己所建议的那样不合理,尽管使用注入依赖关系的接口通常使得在实现需要更大的数字时更容易维护API。依赖关系或其他形式的上下文)。

  2. 当有多种不同的方法来创建对象时,私有构造函数可以更容易地理解构造它的不同方法(例如,哪个对你或,,)更具可读性。换句话说,私有构造函数允许您提供名称更易于理解的工厂函数,然后将构造函数设置为私有,以确保人们仅使用更不言自明的名称。这也常用于生成器模式。例如:new ArrayList(5)ArrayList.createWithCapacity(5)ArrayList.createWithContents(5)ArrayList.createWithInitialSize(5)

    MyClass myVar = MyClass
        .newBuilder()
        .setOption1(option1)
        .setOption2(option2)
        .build();
    

答案 2

我以为有人会提到这一点(第2点),但是..私有构造函数有三种用途:

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

    • 单身 人士
    • 工厂方法
    • 仅静态方法(实用工具)类
    • 仅常量类
  • 以防止叠加(扩展)。如果只创建私有构造函数,则任何类都不能扩展类,因为它不能调用构造函数。这是某种同义词super()final

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