Delegate.notNull和lateinit Kotlin之间的区别

我很困惑,看起来和作品非常相似。 我应该去哪一个?

private var mMediaController by Delegates.notNull<MediaControllerCompat>() 

要么

 lateinit private var mMediaController: MediaControllerCompat 

用法:

  @Subscribe fun connectToSession(token: MediaSessionCompat.Token) { mMediaController = MediaControllerCompat(activity, token) mMediaController.registerCallback(mMediaControllerCallback) } 

这两个模型是相似的,一个先于另一个。 Delegates.notNull() ( api引用 )基于委托属性 ,是原始的,后来lateinit ( Late Initialized Properties )。 既不覆盖所有可能的用例,也不应该使用,除非你可以控制类的生命周期,并确定它们在使用之前会被初始化。

如果后台字段可能是直接设置的,或者你的库不能使用委托,那么你应该使用lateinit ,通常这是大多数人在使用依赖注入时默认的。 从文档 :

通常,声明为具有非null类型的属性必须在构造函数中初始化。 但是,这往往不方便。 例如,属性可以通过依赖注入来初始化,或者在单元测试的设置方法中进行初始化。 在这种情况下,你不能在构造函数中提供一个非null初始值设定项,但是当你引用一个类的内部属性的时候,你还是要避免使用null检查。

如果您使用的类型不被lateinit支持(不支持基本类型),那么您将被迫使用委托。

(lateinit)修饰符只能用于在类的主体内部声明的var属性(不在主构造函数中),只有当属性没有自定义的getter或setter时。 属性的类型必须是非空的,并且不能是原始类型。

您可能还想阅读讨论主题“ 改进lateinit ”。

  • notNull为每个属性创建一个额外的对象。

  • 对象很小,但是如果你有很多属性,对你来说可能很重要。

  • 您不能将notNull委托与直接注入Java字段的外部注入工具一起使用;

  • 您不能创建原始类型(Int,Long等)的lateinit属性。

  • lateinit更便宜,但是当你的属性有一个原始类型时,你可以只使用委托。

来源: https : //discuss.kotlinlang.org/t/notnull-delegate-vs-lateinit/1923/2