对象构造函数和Delegates.notNull

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:在ru.WalletConfig.setClientUrl(WalletConfig.kt)上加载'wallet.config'配置文件:java.lang.NullPointerException

问题是由于命令init块和属性初始值设定项未命中造成的。 如关于类初始化语义的答案中所述。 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设置器,然后尝试调用Delegates.notNull()实例方法。 但是,持有Delegates.notNull()的实例字段尚未设置,因此NPE。

要解决这个问题,你只需要像这样重新排序:

 object WalletConfig { var clientUrl: String by Delegates.notNull() private set init { fill(HashMap<String, String>()) } ... }