我在嘗試在Groovy中使用屬性訪問時遇到問題。看看下面的類:在groovy中攔截LOCAL屬性訪問
class Foo {
Map m = [:]
String bar
void getProperty(String name) {
m.get name
}
def setProperty(String name, value) {
m.set name, value
}
String getBarString() {
return bar // local access, does not go through getProperty()
}
}
它覆蓋getter和setter簡單地放置值成地圖,而不是爲對象的普通財產的空間。抽象地說,這有點愚蠢,但想象一下,不是將數據放入地圖中,而是將其保存到數據庫或其他有用的東西中。
不幸的是,下面的代碼,現在將不起作用:
foo = new Foo()
foo.bar = "blerg" // using foo.bar invokes the setProperty interceptor
assert foo.bar == "blerg" // this will work fine as foo.bar here uses the getProperty interceptor
assert foo.getBarString() == "blerg" // explosion and fire! getBarString accesses bar locally without going through the getProperty interceptor so null will actually be returned.
當然有這個解決方法,可能的setProperty都設置在元屬性和Map值等。然而,所有我的策略我們曾經想過要求程序員特別小心,以確保他們正確地訪問類屬性。
此外,一些建在真棒東西在Groovy(如@Delegate例如)使用直接元屬性訪問,而不是經歷的getProperty所以下面永遠不會成功:
class Meep {
String getMyMeep() {
return "MEEP!!!"
}
}
class Foo {
Map m = [:]
String bar
@Delegate Meep meep
void getProperty(String name) {
m.get name
}
def setProperty(String name, value) {
m.set name, value
}
String getBarString() {
return bar
}
}
foo = new Foo()
foo.meep = new Meep() // uses setProperty and so does not place the Meep in the Map m
foo.getMyMeep()
一個空指針異常是拋出最後一行,因爲@Delegate使用MetaProperty直接訪問(有效地this.meep.getMyMeep()而不是getProperty攔截器。不幸的是,'meep'爲null,儘管getProperty('meep')不會。
In總之我在尋找的是一個解決以下標準的策略:
- 攔截屬性讀/寫啓用自動替代數據存儲爲其他開發商
- 透明或接近透明的界面(我不想讓其他人的生活顯著困難)
- 允許本地使用MetaProperty/this /等訪問變量。訪問方法
在此先感謝!
這將允許我從實例外部訪問裸屬性,而不是通過代理方法。但是,我真正想要做的是能夠攔截**所有**訪問。 我不知道是否有可能重寫給定屬性的MetaProperty.setProperty函數......或者甚至可以幫助。 – 2012-07-13 00:00:51