Reputation: 1606
I am trying to use the @Lazy annotation (http://docs.groovy-lang.org/docs/next/html/documentation/#xform-Lazy) in a trait to initialise an object only if used.
trait MyTrait{
@Lazy String test = {
new Exception().printStackTrace()
return 'test'
}()
}
The object is created regardless is used or not. I have added a printStackTrace in the initialisation closure to make sure I don't call the variable inadvertently. The object gets created when the class implementing the trait is instantiated.
Upvotes: 0
Views: 420
Reputation: 7868
This appears to be a bug. The @Lazy
does not work in trait's. You should create an issue ticket with Groovy for this to be corrected.
To prove the issue, I have extended your code to create a test (run as a simple groovy script) that shows that @Lazy
works for a Class
, but fails the assertion when used on a trait
:
class MyBase{
@Lazy String test = { 'test' }()
}
class TestBaseClass extends MyBase{}
def tb = new TestBaseClass();
//Dump the current state to output an assert test hasn't been initialized
println "Testing @Lazy on a Class.."
println tb.dump()
assert tb.dump().contains('test=null') //FOR A CLASS, THIS WILL SUCCEED
//Access the test property causing initialization
println "Accessing the test property."
assert tb.test
//Dump the current state to output an assert test has now been initialized
println tb.dump()
assert tb.test == 'test'
trait MyTrait{
@Lazy String test = { 'test' }()
}
class TestClass implements MyTrait{}
def t = new TestClass();
//Dump the current state to output an assert test hasn't been initialized
println "\nTesting @Lazy on a Trait.."
println t.dump()
assert t.dump().contains('test=null') //FOR A TRAIT, THIS WILL FAIL THE ASSERTION - A BUG?
//Access the test property causing initialization
println "Accessing the test property."
assert t.test
//Dump the current state to output an assert test has now been initialized
println t.dump()
assert t.test == 'test'
Upvotes: 1