Kotlin 中的私有构造函数有什么用?

ome*_*100 4 constructor kotlin

我是 Kotlin 的新手。我想问一下Kotlin中的私有构造函数有什么用?class DontCreateMe private constructor () { /*...*/ }。我的意思是,如果我们无法创建它的实例,那么该类应该是什么?

Edu*_*edo 6

好吧,评论中的答案是正确的,但因为没有人写出完整的答案。我要去尝试一下。

拥有私有构造函数并不一定意味着对象不能被外部代码使用。它只是意味着外部代码不能直接使用其构造函数,因此必须通过类范围内公开的 API 来获取实例。由于此 API 位于类范围内,因此它可以访问私有构造函数。

最简单的例子是:

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)
}
Run Code Online (Sandbox Code Playgroud)

我见过的最常见的用例是实现单例模式,如 Mojtaba Haddadi 所说,其中外部代码只能访问该类的一个实例。

一个简单的实现是:

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)
}
Run Code Online (Sandbox Code Playgroud)

这经常被使用,以便消耗资源的类仅被实例化一次,或者某些数据片段被整个代码库共享。

请注意,kotlin 使用object 关键字来实现此模式,其优点是线程安全。此外,一些开发人员认为单例是一种反模式

私有构造函数的另一个用例是实现Builder 模式,其中具有复杂初始化的类可以抽象为更简单的 API,因此用户不必处理笨重的构造函数。这个另一个答案解决了它在 kotlin 中的用途。

我所见过的现实生活中 kotlin 代码中最简单的用途之一是stdlib 的Result 实现,它用于更改对象的内部表示。