Groovy中有一種方法可以在類實例化時將代碼添加到構造函數中嗎?我有一個Groovy類(但我不能修改這個特定的源代碼),但我希望有一種方法來注入代碼(也許通過元類),所以我的代碼作爲構造函數的一部分運行(在此情況下只有一個,默認的構造函數)。Groovy將代碼添加到構造函數
感謝, 傑夫
Groovy中有一種方法可以在類實例化時將代碼添加到構造函數中嗎?我有一個Groovy類(但我不能修改這個特定的源代碼),但我希望有一種方法來注入代碼(也許通過元類),所以我的代碼作爲構造函數的一部分運行(在此情況下只有一個,默認的構造函數)。Groovy將代碼添加到構造函數
感謝, 傑夫
您可以重寫構造函數,但它是一個有點棘手,特別是如果你要替換默認的構造函數。您需要爲課程metaClass.constructor
指定一個閉包,閉包應返回一個新實例。棘手的部分是如果你調用你重寫的構造函數,你將進入遞歸循環併產生堆棧溢出。您需要另一種方法來獲取類的實例,例如不同的構造函數。
對於測試,有時可以避開這個限制。通常,首先實例化對象就足夠了,然後重寫構造函數以返回現有實例。例如:
class MyObject {
String something
MyObject() { something = "initialized" }
}
testInstance = new MyObject()
testInstance.something = "overriden"
MyObject.metaClass.constructor = { -> testInstance }
aNewObject = new MyObject()
assert aNewObject.is(testInstance)
assert aNewObject.something == "overriden"
我想我應該能夠使用2個構造函數來得到我需要什麼成就。謝謝。 – 2011-05-06 13:17:29
可以添加新的構造函數或替換舊的構造函數。如果您需要原始的構造函數,你可以使用反射爲:
MyObject.metaClass.constructor = { -> // for the no-arg ctor
// use reflection to get the original constructor
def constructor = MyObject.class.getConstructor()
// create the new instance
def instance = constructor.newInstance()
// ... do some further stuff with the instance ...
println "Created ${instance}"
instance
}
請注意,你有,如果你有參數的構造函數來改變這一狀況,如:
// Note that the closure contains the signature of the constructor
MyObject.metaClass.constructor = { int year, String reason ->
def constructor = MyObject.class.getConstructor(Integer.TYPE, String.class)
def instance = constructor.newInstance(
2014, "Boy, am I really answering a question three years old?")
// ... do some further stuff with the instance ...
println "Created ${instance}"
instance
}
PS:請注意,當您想要添加不存在的構造函數,請使用<<
運算符代替:MyObject.metaClass.constructor << { /* as above */ }
。
通過使用標準Java反射來存儲原始構造函數,您可以繞過解決方案中的限制。例如,這是我做的斯波克測試初始化類(基本噴射):
def setupSpec() {
MockPlexusContainer mockPlexusContainer = new MockPlexusContainer()
def oldConstructor = MY_CLASS.constructors[0]
MY_CLASS.metaClass.constructor = { ->
def mojo = oldConstructor.newInstance()
mockPlexusContainer.initializeContext(mojo)
return mojo
}
}
這被調用一次,但eveytime有人調用構造函數,我得到一個不同的實例,避免清潔值,並確保螺紋安全。
決不這樣做我自己,但是這可能幫助http://groovy.codehaus.org/ExpandoMetaClass+-+Constructors – 2011-05-06 06:37:46
優秀的鏈接,謝謝 – 2011-05-06 13:15:43