Groovy 在这里做啥?
Posted
技术标签:
【中文标题】Groovy 在这里做啥?【英文标题】:What is Groovy doing here?Groovy 在这里做什么? 【发布时间】:2012-03-20 11:43:45 【问题描述】:我试图调试一些使用 mixins 的代码,并且我能够将我的问题简化为这个示例。我有一个通过 mixin 接收方法的父类和一个从父类继承的子类。如果我尝试替换子类实例上的方法,它会起作用除非,我要替换的方法在父类实例被替换之前被调用。如果它已被调用,那么我无法替换它
所以这段代码:
class M
protected foo() println 'foo'
@Mixin(M) class A
def bar() foo()
class B extends A
def b = new B()
def a = new A()
a.bar() //<-- comment out this line and see the difference
b.metaClass.foo = println 'winning'
b.bar()
将产生:
富
富
但是,如果您注释掉第 13 行(带有注释的那一行),您将得到:
获胜
为什么会这样?我希望这在 Groovy 的元类模型的上下文中是有意义的,但我不明白。
这是 Groovy 1.8.6
【问题讨论】:
我也可以在 Groovy 1.8.4 中重现这个。我闻起来像虫子;但我不太喜欢 Groovy 元编程,所以我不知道。 感谢您的说明,如果我最终提交错误,我一定会包括在内。 我会在 groovy 用户邮件列表上问这个问题,对我来说闻起来像一个错误...... 这可能与任何方法处理程序缓存有关吗? 【参考方案1】:metaClass 在方法调用中被查看,mixin 有自己的处理程序。 两者都是延迟加载的,并且是静态的,如果您不调用方法,则不会发生静态延迟加载。 Mixins 优先于 metaClass 覆盖,这就是为什么如果您初始化 A,它会显示 foo 而不会获胜。 元是在它所应用的对象上定义的,以便为每个类解析它,您需要 Object.class.metaClass(即此处为 B.metaClass)。 有趣的是,这会产生:
groovy.lang.MissingMethodException: No signature of method: B.foo() is applicable for argument types: () values: []
Possible solutions: foo(), foo(java.lang.Object), bar(), any(), use([Ljava.lang.Object;), find(groovy.lang.Closure)
在 B 上定义 foo 解决错误:
class B extends A
def foo() println 'not winning'
您的回答是 Mixin 会影响类 Metastore,并且类方法优先于对象 Metastore 方法。
证明:
@Mixin(M)
class B extends A
a.bar() //<-- comment out this line and see the difference
B.metaClass.foo = println 'class winning'
b.metaClass.foo = println 'object winning'
b.bar()
产量:
foo
class winning
另一种方法
class M
protected foo() println 'foo'
@Mixin(M) class A
def bar() foo()
class B extends A
def bar() foo()
class C extends B
def foo() println 'wat'
@Mixin(M)
class D extends C
def b = new B()
def a = new A()
def c = new C()
def d = new D()
a.bar() //<-- comment out this line and see the difference
b.metaClass.foo = println 'winning'
b.bar()
c.metaClass.foo = println 'losing'
c.bar()
d.metaClass.foo = println 'draw'
d.bar()
产量
foo
winning
wat
wat
【讨论】:
您有可以引用此信息的来源吗?我不完全听从您的回答,也找不到有关 Groovy 元存储的任何信息。 所有这些都取自文档并自己摆弄控制台。你的问题很有趣,在我看来,它本身就值得一篇博文。文档的 Dynamic Groovy 页面已经提供了一些答案 groovy.codehaus.org/Per-Instance+MetaClass以上是关于Groovy 在这里做啥?的主要内容,如果未能解决你的问题,请参考以下文章