1. 程式人生 > >kotlin - Delegates.notNull和lateinit之間的差異

kotlin - Delegates.notNull和lateinit之間的差異

The two models are similar, and one predates the other. Delegates.notNull() (api reference) is based on delegated properties and was the original, and later came lateinit (Late Initialized Properties). Neither cover all possible use cases and neither should be used unless you can control the lifecycle of the class and know for sure that they will be initialized before being used.

If the backing field might be set directly, or your library cannot work with a delegate then you should use lateinit and typically it is the default for most people when using with dependency injection. From the docs:

Normally, properties declared as having a non-null type must be initialized in the constructor. However, fairly often this is not convenient. For example, properties can be initialized through dependency injection, or in the setup method of a unit test. In this case, you cannot supply a non-null initializer in the constructor, but you still want to avoid null checks when referencing the property inside the body of a class.

If the type you are using is not supported by lateinit (does not support primitive types) you are then forced to use the delegate.

The (lateinit) modifier can only be used on var properties declared inside the body of a class (not in the primary constructor), and only when the property does not have a custom getter or setter. The type of the property must be non-null, and it must not be a primitive type.

You might also want to read the discussion topic "Improving lateinit".

譯文

這兩個模型是相似的,Delegates.notNull()(api參考)基於委託屬性,是原始的
,後來是lateinit(後期初始化屬性)。不覆蓋所有可以能的用例,除非你能夠控制類的生命週期,並確保它們在使用前初始化。

如果可以以直接設定備份欄位,或者者你的庫不能使用委託,那麼你應該使用lateinit。來自文件的:

通常,宣告為非空型別的屬性必須在建構函式中初始化。然而,這通常是不方便的。例如可以通過依賴項注入或者單元測試的設定方法來初始化屬性。在這種情況下,不能在建構函式中提供非空初始值設定項,但是在引用類中的屬性時仍然要避免null檢查。

如果lateinit(不支援基元型別)不支援你正在使用的型別,則強制你使用委託。

(lateinit)修飾符只能在類(不在主建構函式中)內宣告的var屬性上使用,而且只有在該屬性沒有自定義集合或者設定器時。屬性的型別必須是非空的,並且不能是基元型別。