I'm a newbie in Kotlin. I want to ask what private constructor in Kotlin for? class DontCreateMe private constructor () { /*...*/ }
. I mean what class is supposed to be if we can't create its instance?

- 1,999
- 1
- 10
- 33

- 39
- 1
- 6
-
Private constructors are useful if the class is only meant to contain static methods (i.e. have a companion object in Kotlin), or if it should only be instantiated by methods defined in the class itself, or in its companion object. See the class java.util.Optional, for example. You can create instances of it. But not by calling its constructor. Only using factory methods like of() or ofNullable() or by transforming an Optional into another one with map(). – JB Nizet Dec 14 '19 at 16:33
-
checkout this link : https://refactoring.guru/design-patterns/singleton/java/example , the code is in java but concept is identical – Mojtaba Haddadi Dec 14 '19 at 16:45
-
If you have a private primary constructor, but you have multiple public secondary constructors so that you can limit certain combination of arguments. – EpicPandaForce Dec 14 '19 at 17:00
-
1"if the class is only meant to contain static methods (i.e. have a companion object in Kotlin)" In this case it should just be `object`, not a class with a private constructor and all methods inside companion object. – Alexey Romanov Dec 15 '19 at 07:14
-
@AlexeyRomanov Agreed. That was more of an explanation for private constructors in general, on the JVM. – JB Nizet Dec 15 '19 at 07:30
1 Answers
Well, the answers in the comments are correct, but since nobody wrote a full answer. I'm going to have a go at it.
Having a private constructor does not necessarily mean that an object cannot be used by external code. It just means that the external code cannot directly use its constructors, so it has to get the instances through an exposed API in the class scope. Since this API is in the class scope, it has access to the private constructor.
The simplest example would be:
class ShyPerson private constructor() {
companion object {
fun goToParty() : ShyPerson {
return ShyPerson()
}
}
}
fun main(args: String) {
// outside code is not directly using the constructor
val person = ShyPerson.goToParty()
// Just so you can see that you have an instance allocated in memory
println(person)
}
The most common use case for this that I've seen is to implement the Singleton pattern, as stated by Mojtaba Haddadi, where the external code can only get access to one instance of the class.
A simple implementation would be:
class Unity private constructor() {
companion object {
private var INSTANCE : Unity? = null
// Note that the reason why I've returned nullable type here is
// because kotlin cannot smart-cast to a non-null type when dealing
// with mutable values (var), because it could have been set to null
// by another thread.
fun instance() : Unity? {
if (INSTANCE == null) {
INSTANCE = Unity()
}
return INSTANCE
}
}
}
fun main(args: Array<String>) {
val instance = Unity.instance()
println(instance)
}
This is often used so that classes that are resource consuming are only instantiated once or so that certain pieces of data are shared by the entire codebase.
Be aware that kotlin uses the object keyword to implement this pattern, with the advantage of being thread-safe. Also some developers consider Singletons to be an anti-pattern
Another use case for private constructors would be to implement Builder patterns, where classes that have complex initialization can be abstracted into a simpler API, so the user doesn't have to deal with clunky constructors. This other answer addresses its uses in kotlin.
One of the simplest uses in real life kotlin code that I've seen is on the Result implementation from the stdlib, where it's being used to change the internal representation of the object.

- 762
- 1
- 4
- 16