6 java groovy metaprogramming expandometaclass
Groovy公开了一个ExpandoMetaClass允许您动态地向POJO添加实例和类方法/属性的方法.我想用它来为我的一个Java类添加一个实例方法:
public class Fizz {
// ...etc.
}
Fizz fizz = new Fizz();
fizz.metaClass.doStuff = { String blah -> fizz.buzz(blah) }
Run Code Online (Sandbox Code Playgroud)
这相当于重构Fizz类具有:
public class Fizz {
// ctors, getters/setters, etc...
public void doStuff(String blah) {
buzz(blah);
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题:
这是否doStuff(String blah)仅添加此特定实例Fizz?或者现在所有实例Fizz都有doStuff(String blah)实例方法?
如果是前者,我如何获得Fizz具有doStuff实例方法的所有实例?我知道如果我做了Groovy:
fizz.metaClass.doStuff << { String blah -> fizz.buzz(blah) }
Run Code Online (Sandbox Code Playgroud)
然后,这会添加一个静态类方法Fizz,例如Fizz.doStuff(String blah),但这不是我想要的.我只想要所有实例Fizz现在都有一个名为的实例方法doStuff.想法?
首先,当您添加到 Fizz 主类时,它的实例不会获取该方法,因为实例已经被分解并添加到内存中。
因此,解决此问题的一种方法是使用原始类中的方法签名。因此代替
fizz.doStuff(blah)
调用类的方法。所以
fizz.&doStuff(blah)
这从原始类获取方法签名,但使用实例的属性。然而,正如您可以想象的,由于它调用原始类,所以这是一个稍微繁重的调用。
现在,推出到每个实例的一种替代方法是使实例成为 Fizz 的 ExpandoMetaClass 实例。因此...
Fizz.metaClass.doStuff = {return "blah"}
fizz = new Fizz()
Fizz.metaClass.doOtherStuff = {return "more blah"}
assert fizz.doOtherStuff() == "more blah"
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助
更新:
完整代码示例:
class Fizz{
}
Fizz.metaClass.doOtherStuff = {return "more blah"}
def fizz = new Fizz()
assert fizz.doOtherStuff() == "more blah"
def fizz1 = new Fizz()
assert fizz1.doOtherStuff() == "more blah"
Run Code Online (Sandbox Code Playgroud)