Idiomatic Kotlin: Property Delegates and Lazy

Tompee Balauag
Familiar Android
Published in
4 min readJul 18, 2018
“Drone view of the suburban neighborhood at South Redondo, Redondo Beach, California, United States” by Paul Hanaoka on Unsplash

This article is a part of the Idiomatic Kotlin series. The complete list is at the bottom of the article.

Today, we will be exploring Kotlin’s property delegate and its possible purposes. This is a part of Kotlin’s first class language support for delegation. Class delegation article is available here.

What is Property Delegation?

Property delegation acts the same way as class delegation but this time, on Kotlin properties. The class owning the property can delegate the property accessor calls to a delegate object instead of handling it by itself.

Motivation

There are useful benefits in using property delegation, the most common being lazy initialization. Lazy initialization allows you to defer creation of objects until the moment they are needed. Let us see how to implement lazy initialization manually.

To implement a lazy initialized property, you have to define a backing field that can be initialized anytime. You can use a lateinit var or a nullable type it depends on your preference. Then, manually override the property accessor methods and add your initialization logic. Note that you have to do this to every property you want to lazily initialized. With Kotlin’s property delegation and lazy initialization first class language support, you can now say goodbye to this boilerplate code.

How to create a Property Delegate?

To understand property delegation, you have to be aware that a property in Kotlin is composed of accessor methods and an optional backing field. These methods, called get and set, are automatically generated for you if you do not override them. To implement a property delegate, be aware that the get and set methods are mapped to the getValue and setValue operators so you need to overload them. Luckily for us, there are predefined property delegate interfaces that we can use such as ReadOnlyProperty for val and ReadWriteProperty for var. Let’s take a look at an example.

The name property is delegated to an instance of the NameDelegate class. The NameDelegate class uses a Database instance to query for the name. Let us examine the NameDelegate up close.

The NameDelegate implements the ReadOnlyProperty interface. The ReadOnlyProperty interface overloads the getValue operator method only so you wont have to define the operator keyword on your own. Now, the getValue has two parameters, an instance of the reference class in which the property is defined. Here, it is a generic type so it can be usable for different classes. The second parameter is of type KProperty. KProperty is a class that represents a Kotlin property. You do not have to actually focus on the parameters and what they can do for now, what is important is to familiarize yourself with the operator function definition.

Notice that the custom delegate has no backing field. If you want to store the current value, you have to define a backing field explicitly. Our example does not need a backing field because the getValue is delegated to a database query.

Property delegation under the hood

Let’s see how Kotlin compiles a property delegate.

Kotlin still creates an instance of the delegate and stores it in a field. The property accessor methods are also delegated to the delegate via a direct getValue invocation. Good old fashion Java delegation.

Lazy Initialization

Kotlin standard library already provides us with a lazy delegate. The lazy method accepts a lambda that serves as the property initializer. Initialization is only performed on the first getValue invocation. The value that was created will be returned on successive calls to getValue.

The manual lazy code from above can now be replaced by a single line.

There are other benefits to using the lazy method other that boilerplate code reduction. Thread-synchronization is guaranteed as well and can be configured to your liking.

Bonus: Observables

Kotlin also provides a read/write delegate that can execute a lambda when the setValue method is invoked. This “observable” delegate is useful for cases such as databinding and reactive programming. The syntax for this delegate is as follows:

Check out the other articles in the idiomatic kotlin series. The sample source code for each article can be found here in Github.

  1. Extension Functions
  2. Sealed Classes
  3. Infix Functions
  4. Class Delegation
  5. Local functions
  6. Object and Singleton
  7. Sequences
  8. Lambdas and SAM constructors
  9. Lambdas with Receiver and DSL
  10. Elvis operator
  11. Property Delegates and Lazy
  12. Higher-order functions and Function Types
  13. Inline functions
  14. Lambdas and Control Flows
  15. Reified Parameters
  16. Noinline and Crossinline
  17. Variance
  18. Annotations and Reflection
  19. Annotation Processor and Code Generation

--

--