Delegates.notNull和lateinit Kotlin之间的区别

Sai*_*Sai 24 kotlin

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

private var mMediaController by Delegates.notNull<MediaControllerCompat>()
Run Code Online (Sandbox Code Playgroud)

要么

lateinit private var mMediaController: MediaControllerCompat
Run Code Online (Sandbox Code Playgroud)

用法:

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

Jay*_*ard 23

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

如果可以直接设置支持字段,或者您的库无法与委托一起使用lateinit,那么您应该使用并且通常在使用依赖注入时它是大多数人的默认设置. 来自文档:

通常,必须在构造函数中初始化声明为具有非null类型的属性.但是,这通常不方便.例如,可以通过依赖注入或单元测试的设置方法初始化属性.在这种情况下,您无法在构造函数中提供非null初始值设定项,但在引用类体内的属性时仍希望避免空值检查.

如果不支持您使用的类型lateinit(不支持基本类型),则会强制您使用该委托.

(lateinit)修饰符只能用于在类体(不在主构造函数中)内声明的var属性,并且只能在属性没有自定义getter或setter时使用.属性的类型必须为非null,并且它不能是基本类型.

您可能还想阅读讨论主题" 改善lateinit ".


The*_*olf 13

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

  • 对象很小,但如果你有很多属性,它对你来说很重要.

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

  • 您无法创建基本类型(Int,Long等)的lateinit属性.

  • lateinit更便宜,但是当你的属性具有原始类型时,你只能使用委托.

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