【问题标题】:Scope of Groovy's ExpandoMetaClass?Groovy 的 ExpandoMetaClass 的范围?
【发布时间】:2013-11-18 05:22:10
【问题描述】:

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 的实例方法。想法?

【问题讨论】:

    标签: java groovy metaprogramming expandometaclass


    【解决方案1】:

    首先,当您添加到 Fizz 的主类时,它的实例不会获取方法,因为实例已经被分解并添加到内存中。

    因此,解决此问题的一种方法是使用原始类的方法签名。因此,而不是

    fizz.doStuff(blah)

    调用类的方法。因此

    fizz.&amp;doStuff(blah)

    这会从原始类获取方法签名,但使用实例中的属性。然而正如你所想象的那样,由于它调用了原始类,所以这是一个稍微沉重的调用。

    现在,推送到每个实例的另一种方法是使实例 ExpandoMetaClass 成为 Fizz 的实例。因此...

    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"
    

    【讨论】:

    • 谢谢@mugdho (+1) - 但是你对整个“&doStuff()”的东西有点让我措手不及......你能提供一个完整的代码示例来演示如何使用 ExpandoMetaclass 附加doStuff 作为Fizz 的所有实例的实例方法?再次感谢!
    • +1。为了向元类添加静态方法,请使用Fizz.metaClass.'static'.fooStuff = {.....}
    • @TicketMonster 标记不同之处,他正在向Fizz 类的元类添加方法,而不是fizz 实例。这使得doStuff 可用于所有 Fizz 实例。
    • @TicketMonster 你去。查看 mugdho 答案的更新。
    • 正是我要添加的内容:)。谢谢 dmahapatro!
    猜你喜欢
    • 2023-04-04
    • 1970-01-01
    • 2011-05-13
    • 2019-06-09
    • 2015-11-29
    • 2015-05-15
    • 1970-01-01
    • 1970-01-01
    • 2013-04-18
    相关资源
    最近更新 更多