对象构造函数和Delegates.notNull

时间:2017-02-07 05:47:28

标签: kotlin

object WalletConfig {

    init {
        fill(HashMap<String, String>())
    }

    var clientUrl: String by Delegates.notNull()
        private set

    fun fill(settingMap: Map<String, String>) {
        try {
            clientUrl = settingMap["URL_CLIENT"] ?: ""
        } catch(ex:Exception) { }
    }
}

throw ex:fill:Load&#39; wallet.config&#39;配置文件:ru.WalletConfig.setClientUrl(WalletConfig.kt)中的java.lang.NullPointerException

1 个答案:

答案 0 :(得分:6)

问题是由未命中的init块和属性初始值设定项引起的。正如answer about class initialization semantics中所述。 init 块不是构造函数 - 其代码包含在主构造函数中。

以下示例:

class OrderOfInits {
    constructor() {
        println("constructor")
    }
    init {
        println("A")
    }
    init {
        println("B")
    }
    init {
        println("C")
    }
}

val a = OrderOfInits()

会打印:

A
B
C
constructor

属性委托初始化也是主构造函数的一部分。它们在构造函数中的初始化顺序反映了它们的声明顺序。换句话说,init { fill(...) }初始化程序块调用clientUrl setter,后者又尝试调用Delegates.notNull()实例方法。但是,持有Delegates.notNull()的实例字段尚未设置,因此NPE。

要解决此问题,您只需对其进行重新排序:

object WalletConfig {
    var clientUrl: String by Delegates.notNull()
        private set

    init {
        fill(HashMap<String, String>())
    }
    ...
}