2017-05-26 36 views
9

我很困惑,两个外观和作品非常相似。我应该去哪一个?Delegates.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) 
    } 
+0

这个问题没有标记封闭,有什么别的需要超越目前的答案? –

回答

12

这两种型号都差不多,和一个早于其他。 Delegates.notNull()api reference)基于delegated properties并且是原始的,后来是lateinitLate Initialized Properties)。既不能涵盖所有可能的用例,也不应该使用这些用例,除非您可以控制类的生命周期并确定它们在使用之前将被初始化。

如果后台字段可能是直接设置的,或者您的库无法与委托一起工作,那么您应该使用lateinit,通常这是大多数人在使用依赖注入时的默认设置。 From the docs

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

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

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

你也可能需要阅读的讨论主题为 “Improving lateinit”。

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

  • 该对象很小,但如果您有很多属性,它可能是 对您很重要。

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

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

  • lateinit更便宜,但只有当您的属性具有原始类型时才可以使用委托。

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