Groovy exposes an ExpandoMetaClass
that allows you to dynamically add instance and class methods/properties to a POJO. I would like to use it to add an instance method to one of my Java classes:
public class Fizz {
// ...etc.
}
Fizz fizz = new Fizz();
fizz.metaClass.doStuff = { String blah -> fizz.buzz(blah) }
This would be the equivalent to refactoring the Fizz
class to have:
public class Fizz {
// ctors, getters/setters, etc...
public void doStuff(String blah) {
buzz(blah);
}
}
My question:
Does this add doStuff(String blah)
to only this particular instance of Fizz
? Or do all instances of Fizz
now have a doStuff(String blah)
instance method?
If the former, how do I get all instances of Fizz
to have the doStuff
instance method? I know that if I made the Groovy:
fizz.metaClass.doStuff << { String blah -> fizz.buzz(blah) }
Then that would add a static class method to Fizz
, such as Fizz.doStuff(String blah)
, but that's not what I want. I just want all instances of Fizz
to now have an instance method called doStuff
. Ideas?
Firstly, when you add to the main class of Fizz, its instances do not get the method as the instances have already been factored out and added to memory.
So one way of approaching this is to use the method signature from the original class. Therefore instead of
fizz.doStuff(blah)
call the method of the class. Therefore
fizz.&doStuff(blah)
This gets the method signature from the originating class, but uses the attributes from the instance. However as you can imagine, since its calling the originating class, this is a slightly heavy call.
Now one alternative of pushing out to every instance is to make the instances ExpandoMetaClass instances of Fizz. Hence...
Hope this helps
UPDATE:
Full code example: