September 18, 2009

Groovy Goodness: Lazy Initialization of Properties

Sometimes we want the value of a property only to be calculated on first use. The calculation of the value can be time consuming or requires a lot of resources. In Groovy we can use the @Lazy transformation to define a property we want to be initialized lazily. The value is not calculated or assigned until the value is requested. The transformation also allows a soft parameter. This defines the field as soft reference.

class Get {
    String url
    @Lazy URL urlObj = { url?.toURL() }()  // Closures allowed to create object.
    // Will use a soft reference.
    @Lazy(soft=true) String text = urlObj?.text

def g = new Get(url: '') 
assert '' == g.url
assert g.dump().contains('text=null')
assert g.dump().contains('urlObj=null')

// Now we access the urlObj property, so the value
// is calculated and we can access it.
assert g.urlObj
assert 'http' == g.urlObj.protocol
assert '' ==
assert '/' == g.urlObj.path

// Now we access the text property, so the contents
// is fetched from the URL.
assert g.text
assert g.text.contains('Messages from mrhaki')