简体   繁体   中英

What private constructor in Kotlin for?

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM