Groovy公开了一个ExpandoMetaClass
,它允许您动态地向POJO添加实例和类方法/属性。我想用它来为我的一个Java类添加一个实例方法:
public class Fizz {
// ...etc.
}
Fizz fizz = new Fizz();
fizz.metaClass.doStuff = { String blah -> fizz.buzz(blah) }
这相当于重构Fizz
类:
public class Fizz {
// ctors, getters/setters, etc...
public void doStuff(String blah) {
buzz(blah);
}
}
我的问题:
这是否仅将doStuff(String blah)
添加到此Fizz
的特定实例中?或者Fizz
的所有实例现在都有doStuff(String blah)
实例方法?
如果是前者,如何让Fizz
的所有实例都拥有doStuff
实例方法?我知道如果我做了Groovy:
fizz.metaClass.doStuff << { String blah -> fizz.buzz(blah) }
然后,这会向Fizz
添加静态类方法,例如Fizz.doStuff(String blah)
,但这不是我想要的。我只希望Fizz
的所有实例现在都有一个名为doStuff
的实例方法。想法?
答案 0 :(得分:3)
首先,当你添加到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"
希望这有帮助
<强>更新强>
完整代码示例:
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"