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 回答