构造函数可以是私有的吗?私有构造函数有什么用处?
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();
我本以为有人会提到这一点(第二点),但是...私有构造函数有三个用途:
防止在以下情况下在对象外部实例化:
防止子类化(扩展)。如果只有一个私有构造函数,那么没有任何类可以扩展你的类,因为它无法调用super()
构造函数。这在某种程度上相当于final
重载构造函数 - 由于重载方法和构造函数,一些可能是私有的,一些可能是公共的。特别是在存在非公共类的情况下,您可能会创建一个公共构造函数来创建该类的实例,然后将其传递给私有构造函数。
final
关键字作为实现这一点的一种方式。 - Bozho是的。
这样做可以控制类的实例化方式。如果将构造函数设为私有,然后创建可见的构造方法用于返回类的实例,你就可以限制实例的数量(通常保证只有一个实例存在),或者回收实例或其他与构造相关的任务。
使用 new x()
永远不会返回 null
,但是使用工厂模式,可以返回 null
,甚至返回不同的子类型。
你也可以用于一个没有实例成员或属性,只有静态成员的类——比如一个实用函数类。
如果一个类中的所有方法都是静态的,那么使用私有构造函数是一个很好的选择。
在Java中定义私有构造函数的原因如下:
控制Java对象的实例化,防止创建对象的实例。
防止类被子类化。
在实现单例模式时具有特殊优势,使用私有构造函数可以控制整个应用程序的实例创建。
当您想要定义所有常量并且不再需要其实例的类时,我们将该类声明为私有构造函数。
是的。
私有构造函数用于防止实例初始化,例如您在Java中使用的Math final类。单例模式也使用私有构造函数。
//... 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;
}
}
}
是的,构造函数可以是私有的。私有构造函数防止任何其他类实例化私有构造函数的示例。
public class CustomHttpClient {
private static HttpClient customHttpClient;
/** A private Constructor prevents any other class from instantiating. */
private CustomHttpClient() {
}}
lwjgl3
(beta)的jar文件,我在org.lwjgl.Version
中发现了一个私有构造函数。这就是我来到这里的原因。有趣的是,这个类还有它自己的main
。Java很奇怪。 - Braden Best