2

Groovy で @Mixin アノテーションを使用したいと考えています。これは、プライベート メソッドとフィールドを混在させることを除いて、まさに私が望むことを行います。

class A {
def private fooA() {
        println("A")
    }
}

@Mixin(A)
class B {
    def fooB() {
        println("B")
   }
}

このコードを実行すると

static main(args)
{
    def b = new B()
    println(b.fooA())
    B.metaClass.fooA = {throw new MissingMethodException()};
    println(b.fooA())
}

最初にプライベート メソッド A.fooA を呼び出し、"A" を出力します。次に、そのプライベート メソッドが削除され、クラス A に混在するクライアント クラス B から呼び出すことができなくなります。

私の質問は、どうすればこれを一般的な方法で達成できるのでしょうか? @Mixin アノテーションを拡張できます。問題は、私が Groovy を初めて使用することであり、AST 変換の記述方法について見つけるべき情報があまりないことです。それについての章全体がある新しい Groovy in Action の本はまだ出ていません。

代わりに @Delegate を使用できますが、委任先のクラスの変数を宣言する必要があります。これは私が望むものではありません。私のものを使用して開発者に単に @Mixin で彼のクラスに注釈を付けて、私のものを混ぜ合わせるように伝えることができればいいと思います。それだけです。また、クラスのプライベート メソッドとフィールドが、混在するクラスの内部コードを壊しているユーザーによって呼び出されないことを確認できます。

これを成し遂げるために私がどの方向に向けるべきかについてのヒントはありますか? ありがとう、オリバー

4

1 に答える 1

2

Groovy の重点ではないことに気がついたと思います。非公開メンバーの非表示のサポートには、一般的 に問題があります。

あなたの特定のケースでは、新しいバグ (?) に遭遇した可能性があります。@Mixin調べてみると、に到達するコードを呼び出すための AST 変換のように見えますMixinInMetaClass.mixinClassesToMetaClass()。これは、非パブリック メソッドをターゲット メタクラス (クラス B のメタクラス) にコピーしないように努めています。それらはあなたのメソッドのリストに表示されないb.metaClassので、それは正しいようです。

への呼び出しb.fooA()は、存在しないプロパティを使用するか、b で存在しないメソッドを呼び出そうとするまで (何らかの方法で) 機能します。(または電話b.metaClass.initialize())。その後、行方不明の苦情が寄せられますfooA()

したがって、Groovy でアクセス修飾子を動作させるために多大な労力を費やすかどうかはわかりませんが、その道を歩み続ける場合は、クラスの初期化コードを記述して、あなたのようなことを行う必要があるかもしれません。上記で行った、または上でinitialize()述べたように悪いプロパティを呼び出します。このコードの一部を独自のクラスに入れることもできますASTTransformationが、私は試していません。ソースを取得して、 を参照できますorg.codehaus.groovy.ast.MixinASTTransformation

于 2012-11-24T05:14:10.763 に答える