是否可以在Groovy中侦听超类属性的更改?

是否可以在Groovy中侦听超类属性的更改?,groovy,Groovy,我想为一个属性创建一个“重载”setter,我想将其保留在trait中。然后,实现trait的任何子类都将使用它们自己的getter,而不是trait的setter。我不想向现有属性添加任何额外的注释。这里有一个澄清: trait Tr { abstract String getS() void setS(String value) { ((GroovyObject) this).setProperty('s', value) reloadOnSC

我想为一个属性创建一个“重载”setter,我想将其保留在trait中。然后,实现trait的任何子类都将使用它们自己的getter,而不是trait的setter。我不想向现有属性添加任何额外的注释。这里有一个澄清:

trait Tr {
    abstract String getS()
    void setS(String value) {
        ((GroovyObject) this).setProperty('s', value)
        reloadOnSChange()
    }

    void reloadOnSChange() {
        // do something when S is changed
    }
}

class Cl implements Tr {
    String s
}

Cl cl = new Cl()
cl.s = 'hello world' // reloadOnSChange should be called

这样的属性侦听器可能吗?

如果您想使用trait,那么您必须与实现
void-getS(String-value)
方法不同,因为Groovy编译器生成的
Cl.getS(String-value)
方法会隐藏在
Tr
trait中实现的方法

或者,您的trait可以提供
void setProperty(字符串名称、对象值)
方法的实现,如果为属性
s
调用该方法,它将执行
reloadOnSChange()
方法。考虑下面的例子:

trait Tr{
抽象字符串get()
抽象空集(字符串s)
void重载更改(){
//当S改变时做些什么
println“重新加载”
}
void setProperty(字符串名称、对象值){
metaClass.setProperty(此、名称、值)
如果(名称='s'){
重载更改()
}
}
}
类Cl实现Tr{
串
}
Cl=新的Cl()
cl.s=‘你好,世界’
println“Dump:${cl.Dump()}”
输出:

RELOAD
Dump: <Cl@6580cfdd s=hello world>
重新加载
转储:
主要的缺点是,这个
setProperty
方法将对每个属性执行,因此它可能会产生一些开销。在某些情况下,JIT应该优化代码,并确保只有当属性名等于
s
时才执行该
if
语句