GitHub   @OpenKivaKit Twitter Zulip Chat RSS Feed Java Code Geeks Mailing List

State(Art)

Jonathan's thoughts on the state of the art in software design.

2021.07.03

Lazy initialization as a Java design pattern  

It would be interesting for Java to have a lazy keyword. This imaginary keyword would only evaluate the expression to the right of the equals sign when the reference on the left side is accessed. Code using this keyword might look like this:

private lazy Map<Key, Value> lazyMap = createMap();

[...]

lazyMap.put(key, value);

Here, just before lazyMap.put() is executed, the createMap() method would be called and its value assigned to lazyMap.

Instead, a common and less succinct idiom in Java is something like this:

private Map<Key, Value> lazyMap;

[...]

if (lazyMap == null)
{
    lazyMap = createMap():
}

lazyMap.put(key, value);


Lazy

We can’t (easily) introduce the lazy keyword that we’d like into Java, but we can create a class with similar functionality:

public class Lazy<Value>
{
    /**
     * Factory method to create a Lazy object with the given value factory
     */
    public static <V> Lazy<V> of(Factory<V> factory)
    {
        return new Lazy<>(factory);
    }

    private Value value;

    private Factory<Value> factory;

    protected Lazy(final Factory<Value> factory)
    {
        this.factory = factory;
    }
    
    public synchronized Value get()
    {
        if (value == null)
        {
            value = factory.newInstance();
        }
        return value;
    }
}

Lazy can reduce the four lines of if-null check boilerplate above to these two lines:

private Lazy<Map<Key, Value>> lazyMap = Lazy.of(this::createMap);

[...]

lazyMap.get().put(key, value);

True, it’s not quite as nice as having a lazy keyword, but it improves readability by making the flow of code easier to follow.


Code

The Lazy class is available in kivakit-kernel in the KivaKit project.

<dependency>
    <groupId>com.telenav.kivakit</groupId>
    <artifactId>kivakit-kernel</artifactId>
    <version>${kivakit.version}</version>
</dependency>


Questions? Comments? Tweet yours to @OpenKivaKit or post here:


Copyright © 2021 Jonathan Locke