委托.notNull和后期初始化Kotlin之间的差异

vof42yt1  于 2023-02-16  发布在  Kotlin
关注(0)|答案(3)|浏览(223)

我很困惑,两个外观和工作都很相似。我应该去哪一个?

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)
    }
bxjv4tth

bxjv4tth1#

这两个模型是相似的,并且一个先于另一个。Delegates.notNull()api reference)基于delegated properties,并且是原始的,并且后来出现了lateinit(Late Initialized Properties)。这两个模型都没有覆盖所有可能的用例,并且都不应该使用,除非您可以控制类的生命周期并且确信它们将在使用之前被初始化。
如果支持字段可以直接设置,或者你的库不能使用委托,那么你应该使用lateinit,通常它是大多数人使用依赖注入时的默认值。
通常,声明为具有非null类型的属性必须在构造函数中初始化。但是,这通常并不方便。例如,属性可以通过依赖项注入初始化,或者在单元测试的setup方法中初始化。在这种情况下,您不能在构造函数中提供非null初始值设定项,但您仍然希望在类主体内引用属性时避免null检查。
如果lateinit不支持您正在使用的类型(不支持基元类型),则强制您使用委托。
(lateinit)修饰符只能用于在类主体内声明的var属性(不在主构造函数中),并且只能在该属性没有自定义getter或setter时使用。属性的类型必须为非null,并且不能为基元类型。
您可能还想阅读讨论主题“Improving lateinit"。

2nc8po8w

2nc8po8w2#

  • notNull为每个属性创建一个额外的对象。
  • 对象很小,但是如果你有很多属性,它对你来说就很重要了。
  • 不能将notNull委托与直接注入Java字段的外部注入工具一起使用;
  • 您不能创建基元类型(Int、Long等)的lateinit属性。
  • lateinit更便宜,但是当属性具有基元类型时,只能使用委托。

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

slhcrj9b

slhcrj9b3#

除其他答案外:@BeforeEach方法不被识别为lateinit var的初始化,因此在这里使用var ... by Delegates.notNull<...>()将是替代。

相关问题