What’s Really Going On

by lazy is really two things: by and lazy. by sets up a property delegate, while lazy is a particular delegate with particular behavior.

by

A Kotlin property is made up of a field, a getter, and a setter. Frequently, the getter and setter are code-generated for us.

There are basically two ways to replace those code-generated accessors:

  1. Override them with custom implementations directly
  2. Redirect them to a property delegate

The expression to the right of by needs to evaluate to a property delegate. That delegate will have getValue() and setValue() functions, and those functions will replace the stock getter and setter, respectively. So, when you try to read the property value, the delegate’s getValue() function is called, and when you try to write the property value, the delegate’s setValue() function is called. Whatever those functions do represent what the property does.

lazy

lazy() is a Kotlin-supplied top-level function that returns a Lazy property delegate.

The lazy() function takes an “initializer” function type, usually supplied in the form of a lambda expression. That gets passed along to the Lazy property delegate. When getValue() is called on the Lazy, if it has not executed the initializer yet, it does so and uses that as the initial value to return from getValue(). It holds onto this value in its own property, and it uses that property for all other getValue() and setValue() calls.

Creating the Lazy itself is cheap. Only if you access the property and trigger the getValue() call on the Lazy will we wind up executing your lambda expression and incurring its expenses (CPU time, memory usage, etc.).


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.