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

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

244774 次浏览

是的。

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

执行new x()永远不会返回null,但是使用工厂模式,你可以返回null,甚至返回不同的子类型。

也可以将它用于没有实例成员或属性,只有静态成员或属性的类——就像在实用函数类中一样。

私有构造函数阻止调用者显式实例化类 参见PrivateConstructor

的进一步信息

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

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

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

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

  1. 创建一个uninstantiable类只是一个收集相关的静态函数(这基本上是一个单例,但如果它是无状态的,静态函数操作严格的参数而不是类的状态,这并不是像我之前不合理的方法自我似乎表明,使用一个接口,虽然是依赖注入通常更容易保持API的实现需要大量依赖关系或其他形式的上下文)。

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

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

是的,它可以。私有构造函数的存在是为了防止类被实例化,或者因为构造只在内部发生,例如工厂模式。更多信息请参见在这里

是的,它用于防止实例化和随后重写。这最常用于单例类中。

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

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

    • 单例
    • 工厂方法
    • 纯静态方法(实用程序)类
    • <李> constants-only类< br > 李。< / > 李< / ul > < / >
    • 防止分层(扩展)。如果只创建私有构造函数,则没有类可以扩展你的类,因为它不能调用super()构造函数。这是final的某种同义词

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

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

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

  2. 它不允许类被子类化

  3. 当实现单例模式时,这有一个特殊的优势,私有构造函数用于它,并控制为整个应用程序创建实例。

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

是的。

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

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

是的,类可以有一个私有构造函数。需要禁止从其他类访问构造函数,并在定义的类中保持它的可访问性。

为什么要只在内部创建类的对象?出于任何原因都可以这样做,但一个可能的原因是您想实现单例对象。单例是一种设计模式,它只允许创建类的一个实例,这可以通过使用私有构造函数来实现。

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

是的,构造函数可以是私有的。私有构造函数阻止任何其他类实例化私有构造函数的示例

public class CustomHttpClient {
private static HttpClient customHttpClient;


/** A private Constructor prevents any other class from instantiating. */
private CustomHttpClient() {
}}

根据我的说法,我们可以将构造函数声明为私有,并且我们 可以在类中使用静态方法获取子类中该类的实例,在类中我们声明构造函数,然后返回类对象。我们将这个方法归为子类 通过使用classname.method name bcz,它是静态方法,我们将获得声明const的类的实例。< / p >

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

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

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

  1. 单例设计模式
  2. 限制创建实例的数量
  3. 使用静态工厂方法为对象创建提供有意义的名称
  4. 静态实用类或常量类
  5. 防止子类化 . bb0 . bref ="http://codepumpkin.com/use-private-constructor-java/#p5" rel="noreferrer">
  6. 建造者设计模式,因此为创建不可变类

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

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

//... 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类

受Robert C. Martin的“Clean Code"的启发,我整理了一个例子:

/**
When overloading constructors, it is best practise to only allow the use of
different constructors than the standart one by explicitly enforcing the
useage of a static function to highlight the use of the overloaded constructor


in example:
Animal a = Animal.CreateInsectOrArachnia(2, "black", 8); //hatch a black widow
*/




class Animal
{
private int size;
private String color;
private int legs;


public Animal(int size, String color)
{
this.size = size;
this.color = color;
this.legs = 4;
}


//will prevent the instanciation of Animal with this constructor
private Animal(int size, String color, int legs)
{
this.size = size;
this.color = color;
this.legs = legs;
}




public static Animal CreateInsectOrArachnia(int size, String color, int legs)
{
return new Animal (size, color, legs);
}


}

Martins明确指出,应该阻止用户访问“标准构造函数”以外的构造函数;并且应该强制使用静态初始化函数来强调“您所做的可能没有错,但它与该类的预期用法不同”;

[他没有使用这个确切的措辞,我试图把它挤进这个定义-对不起,罗伯特:^)]

作为旁注,完全可以将类中唯一的构造函数(即标准构造函数)完全声明为private,并让静态函数返回类实例-请参阅单例模式。但是,非常不鼓励实现单例模式,除非在一些通信只在一个方向上流动的用例中,例如在编写记录器类时