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


当前回答

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

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

下面是私有构造函数的一些用法:

单例设计模式 限制创建实例的数量 使用静态工厂方法为对象创建提供有意义的名称 静态实用类或常量类 防止子类化 构建器设计模式,从而创建不可变类

其他回答

是的,构造函数可以是私有的。这个有不同的用法。其中一种用途是用于单例设计反模式,我建议您不要使用这种反模式。另一个更合理的用途是委托构造函数;你可以有一个构造函数它有很多不同的选项这是一个实现细节,所以你把它设为私有,但是你剩下的构造函数都委托给它。

作为委托构造函数的一个例子,下面的类允许您保存一个值和一个类型,但它只允许您为类型的子集这样做,因此需要将通用构造函数设置为私有,以确保只使用允许的类型。公共私有构造函数有助于代码重用。

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

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

再举几个使用私有构造函数的例子:

To create an uninstantiable class that is just a collection of related static functions (this is basically a singleton, but if it is stateless and the static functions operate strictly on the parameters rather than on class state, this is not as unreasonable an approach as my earlier self would seem to suggest, though using an interface that is dependency injected often makes it easier to maintain the API when the implementation requires larger numbers of dependencies or other forms of context). When there are multiple different ways to create the object, a private constructor may make it easier to understand the different ways of constructing it (e.g., which is more readable to you new ArrayList(5) or ArrayList.createWithCapacity(5), ArrayList.createWithContents(5), ArrayList.createWithInitialSize(5)). In other words, a private constructor allows you to provide factory function's whose names are more understandable, and then making the constructor private ensures that people use only the more self-evident names. This is also commonly used with the builder pattern. For example: MyClass myVar = MyClass .newBuilder() .setOption1(option1) .setOption2(option2) .build();

由于以下原因,可以在Java中定义私有构造函数

为了控制Java对象的实例化,它不允许您创建对象的实例。 它不允许类被子类化 在实现单例模式时,这有一个特殊的优势,它使用私有构造函数,并控制为整个应用程序创建实例。 当你想要一个定义了所有常量的类,并且不再需要它的实例时,我们将这个类声明为私有构造函数。

私有构造函数防止调用者显式实例化类 请参阅PrivateConstructor的进一步信息

私有构造函数背后的基本思想是限制JVM从外部实例化类,但是如果一个类有参数构造函数,那么它就会推断该类是有意实例化的。

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

是的,它可以。我认为这是另一个有用的例子:

//... ErrorType.java
public enum ErrorType {
    X,
    Y,
    Z
}

//... ErrorTypeException.java
import java.util.*;
import java.lang.*;
import java.io.*;

//Translates ErrorTypes only
abstract public class ErrorTypeException extends Exception {
    private ErrorTypeException(){}

    //I don't want to expose thse
    static private class Xx extends ErrorTypeException {}
    static private class Yx extends ErrorTypeException {}
    static private class Zx extends ErrorTypeException {}

    // Want translation without exposing underlying type
    public static Exception from(ErrorType errorType) {
        switch (errorType) {
            case X:
                return new Xx();    
            case Y:
                return new Yx();
            default:
                return new Zx();
        }
    }

    // Want to get hold of class without exposing underlying type
    public static Class<? extends ErrorTypeException> toExceptionClass(ErrorType errorType) {
        switch (errorType) {
            case X:
                return Xx.class;    
            case Y:
                return Yx.class;
            default:
                return Zx.class;
        }
    }
}

在上面的例子中,它阻止抽象类被任何派生类实例化,除了它的静态内部类。抽象类不能是final类,但在这种情况下,私有构造函数使它有效地成为所有非内部类的final类