Can a constructor in Java be private?
Can a constructor be private? How is a private cons开发者_JAVA百科tructor useful?
Yes, a constructor can be private. There are different uses of this. One such use is for the singleton design anti-pattern, which I would advise against you using. Another, more legitimate use, is in delegating constructors; you can have one constructor that takes lots of different options that is really an implementation detail, so you make it private, but then your remaining constructors delegate to it.
As an example of delegating constructors, the following class allows you to save a value and a type, but it only lets you do it for a subset of types, so making the general constructor private is needed to ensure that only the permitted types are used. The common private constructor helps code reuse.
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;
}
}
Edit
Looking at this answer from several years later, I would like to note that this answer is both incomplete and also a little bit extreme. Singletons are indeed an anti-pattern and should generally be avoided where possible; however, there are many uses of private constructors besides singletons, and my answer names only one.
To give a couple more cases where private constructors are used:
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)
orArrayList.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();
I expected that someone would've mentioned this (the 2nd point), but.. there are three uses of private constructors:
to prevent instantiation outside of the object, in the following cases:
- singleton
- factory method
- static-methods-only (utility) class
- constants-only class
.
to prevent sublcassing (extending). If you make only a private constructor, no class can extend your class, because it can't call the
super()
constructor. This is some kind of a synonym forfinal
overloaded constructors - as a result of overloading methods and constructors, some may be private and some public. Especially in case when there is a non-public class that you use in your constructors, you may create a public constructor that creates an instance of that class and then passes it to a private constructor.
Yes it can. A private constructor would exist to prevent the class from being instantiated, or because construction happens only internally, e.g. a Factory pattern. See here for more information.
Yes.
This is so that you can control how the class is instantiated. If you make the constructor private, and then create a visible constructor method that returns instances of the class, you can do things like limit the number of creations (typically, guarantee there is exactly one instance) or recycle instances or other construction-related tasks.
Doing new x()
never returns null
, but using the factory pattern, you can return null
, or even return different subtypes.
You might use it also for a class which has no instance members or properties, just static ones - as in a utility function class.
Well, if all of your methods in a class are static, then a private constructor is a good idea.
Yes. Class can have private constructor. Even abstract class can have private constructor.
By making constructor private, we prevent the class from being instantiated as well as subclassing of that class.
Here are some of the uses of private constructor :
- Singleton Design Pattern
- To limit the number of instance creation
- To give meaningful name for object creation using static factory method
- Static Utility Class or Constant Class
- To prevent Subclassing
- Builder Design Pattern and thus for creating immutable classes
Private Constructors can be defnied in the Java for the following reasons
To have control on the instantiation of the Java objects, it wont allow you to create an instance of an object.
It wont allow the class to be Subclassed
This has a special advantage when implementing the singleton Pattern, Private contstructors are used for it and have a control on the creating the instance for the whole application.
when you want to have a class with all constants defined and Does not require its instance any more, then we declare that class as a private constructor.
Yes.
A private constructor is used to prevent instance initializing, such as the Math final class you use in java. Singleton also use private constructor
Yes, class can have a private constructor. It is needed as to disallow to access the constructor from other classes and remain it accessible within defined class.
Why would you want objects of your class to only be created internally? This could be done for any reason, but one possible reason is that you want to implement a singleton. A singleton is a design pattern that allows only one instance of your class to be created, and this can be accomplished by using a private constructor.
yes a constructor can be private. A private Constructor prevents any other class from instantiating example of private constructor
public class CustomHttpClient {
private static HttpClient customHttpClient;
/** A private Constructor prevents any other class from instantiating. */
private CustomHttpClient() {
}}
Can a constructor be private? How is a private constructor useful?
Yes it can. I consider this another example of it being useful:
//... 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;
}
}
}
In the case here above, it prevents the abstract class from being instantiated by any derived class other than it's static inner classes. Abstract classes cannot be final, but in this case the private constructor makes it effectively final to all classes that aren't inner classes
Private constructors prevent a class from being explicitly instantiated by callers see further information on PrivateConstructor
Yes and it is used to prevent instantiation and subsequently overriding. This is most often used in singleton classes.
Inspired by Robert C. Martin's "Clean Code", example I fiddled together:
/**
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 explicitly states that users should be prevented from accessing constructors other than the "standart constructor" and should be forced to use static initialisation functions to underline that "what you do may not be wrong but it differs from expected useage of this class"
[he did not use this exact wording, i tried to squeeze it into this definition - sorry Robert :^) ]
As a side note, it is totally okay to completely declare the only constructor in a class (aka standart-constructor) as private and have a static function return a class instance - see singleton pattern. it is highly discouraged to implement a singleton pattern tho, except maybe for some use-cases where communication only flows in one direction, f.e. when writing a logger class
Basic idea behind having a private constructor is to restrict the instantiation of a class from outside by JVM, but if a class having a argument constructor, then it infers that one is intentionally instantiating.
According to me we can declare constructor as a private and also we
can get the instance of that class in the subclass by using static method in class in which we declare constructor and then return class object. we class this method from to the sub class
by using classname.method
name bcz it is static method and the we will get the instance of class in which we declare const.
精彩评论