7

Groovy は、ExpandoMetaClassインスタンスおよびクラスのメソッド/プロパティを POJO に動的に追加できるようにする を公開します。これを使用して、Java クラスの 1 つにインスタンス メソッドを追加したいと思います。

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を持つすべてのインスタンスを取得するにはどうすればよいですか? doStuffGroovyを作成した場合、次のことがわかります。

fizz.metaClass.doStuff << { String blah -> fizz.buzz(blah) }

次にFizz、 などの静的クラス メソッドを に追加しますFizz.doStuff(String blah)が、それは私が望むものではありません。Fizzのすべてのインスタンスに、 というインスタンス メソッドを持たせたいだけですdoStuff。アイデア?

4

1 に答える 1

3

まず、Fizz のメイン クラスに追加すると、そのインスタンスは既に分解されてメモリに追加されているため、メソッドを取得しません。

したがって、これにアプローチする 1 つの方法は、元のクラスのメソッド シグネチャを使用することです。したがって、代わりに

fizz.doStuff(blah)

クラスのメソッドを呼び出します。したがって

fizz.&doStuff(blah)

これは元のクラスからメソッド シグネチャを取得しますが、インスタンスの属性を使用します。ただし、ご想像のとおり、元のクラスを呼び出すため、これは少し重い呼び出しです。

すべてのインスタンスにプッシュする別の方法の 1 つは、インスタンスを 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"
于 2013-11-06T20:50:08.267 に答える